Strict Standards: Redefining already defined constructor for class wpdb in /www/htdocs/w006f36b/wp-includes/wp-db.php on line 49

Deprecated: Assigning the return value of new by reference is deprecated in /www/htdocs/w006f36b/wp-includes/cache.php on line 35

Strict Standards: Redefining already defined constructor for class WP_Object_Cache in /www/htdocs/w006f36b/wp-includes/cache.php on line 400

Strict Standards: Declaration of Walker_Page::start_lvl() should be compatible with Walker::start_lvl($output) in /www/htdocs/w006f36b/wp-includes/classes.php on line 534

Strict Standards: Declaration of Walker_Page::end_lvl() should be compatible with Walker::end_lvl($output) in /www/htdocs/w006f36b/wp-includes/classes.php on line 534

Strict Standards: Declaration of Walker_Page::start_el() should be compatible with Walker::start_el($output) in /www/htdocs/w006f36b/wp-includes/classes.php on line 534

Strict Standards: Declaration of Walker_Page::end_el() should be compatible with Walker::end_el($output) in /www/htdocs/w006f36b/wp-includes/classes.php on line 534

Strict Standards: Declaration of Walker_PageDropdown::start_el() should be compatible with Walker::start_el($output) in /www/htdocs/w006f36b/wp-includes/classes.php on line 553

Strict Standards: Declaration of Walker_Category::start_lvl() should be compatible with Walker::start_lvl($output) in /www/htdocs/w006f36b/wp-includes/classes.php on line 649

Strict Standards: Declaration of Walker_Category::end_lvl() should be compatible with Walker::end_lvl($output) in /www/htdocs/w006f36b/wp-includes/classes.php on line 649

Strict Standards: Declaration of Walker_Category::start_el() should be compatible with Walker::start_el($output) in /www/htdocs/w006f36b/wp-includes/classes.php on line 649

Strict Standards: Declaration of Walker_Category::end_el() should be compatible with Walker::end_el($output) in /www/htdocs/w006f36b/wp-includes/classes.php on line 649

Strict Standards: Declaration of Walker_CategoryDropdown::start_el() should be compatible with Walker::start_el($output) in /www/htdocs/w006f36b/wp-includes/classes.php on line 674

Deprecated: Assigning the return value of new by reference is deprecated in /www/htdocs/w006f36b/wp-includes/query.php on line 15

Deprecated: Assigning the return value of new by reference is deprecated in /www/htdocs/w006f36b/wp-includes/theme.php on line 505
MauriceK, caught between dev and drums » Meep meep… midi midi… meep meep

August 20, 2007

Meep meep… midi midi… meep meep

Category: Development — kaldor @ 10:23 pm

Deprecated: preg_replace(): The /e modifier is deprecated, use preg_replace_callback instead in /www/htdocs/w006f36b/wp-includes/formatting.php on line 76

Deprecated: preg_replace(): The /e modifier is deprecated, use preg_replace_callback instead in /www/htdocs/w006f36b/wp-includes/formatting.php on line 83

Some of you already know that since some time I try to learn how to play the piano. Although I bought the Cubase application from Steinberg, I was very unhappy with the startup time. It took around one minute just to be able to start playing. In case you want to rehearse a little bit, that is very inconvenient.

As a developer only one solution comes to your mind: “Write your own stuff”. As I am more into developing the background and engines, I investigated on the MIDI C++ support on Windows and I was fairly surprised how easy it is to get reasonable results. These have been integrated into a little Qt library which handles all native MIDI events for you. Since the GPL exception added by Trolltech with the Qt 4.3.2 release I am now also able to publish this code under BSD license, so feel free to do with it, whatever you like to.

Ok, that explains one thirth of the topic, but why Meep? It has multiple backgrounds. First is, I wanted to quote a friend of mine, as we had some long discussions about libmidi3.so :) But mostly it was because of the reason that this is the first thing coming to your mind when you think of MIDI. MIDI? Isn’t that this crap, which only does meep, meep? It always takes some effort to get usable results out of your MIDI device and/or application. Finally I wanted to get rid of the “Kald-” prefixes like in Kaldience and Kaldile.

For code and examples continue reading…

Ok, let’s consider the situation, we want to know what MIDI devices are currently available on my system. Codewise, this looks simply like this:

Meep::DeviceHandler handler;
QList < meep::deviceinfo > devices = handler.availableDevices();

DeviceInfo is a class with the following structure:

class MEEP_EXPORT DeviceInfo{
public:
DeviceInfo(QObject* parent=0);
~DeviceInfo();
inline QString deviceName() const {return m_name;}
inline DeviceType deviceType() const {return m_type;}
inline int deviceId() const {return m_id;}
private:
friend class DeviceHandler;
friend class DeviceHandlerPrivate;
QString m_name;
Meep::DeviceType m_type;
int m_id;

};

Pretty easy, isn’t it? But how does that help you, when you want to react to MIDI devices? Take a look at the declaration of a device instance:

class MEEP_EXPORT Device : public QObject{

Q_OBJECT
Q_ENUMS(Meep::DeviceType)
Q_DECLARE_PRIVATE(Meep::Device);
Q_PROPERTY(QString name READ name)
Q_PROPERTY(DeviceType type READ type)
Q_PROPERTY(DeviceInfo info READ info)

public:
Device(const QString &name, QObject *parent = 0);
Device(const Meep::DeviceInfo &info, QObject *parent = 0);

virtual ~Device();
bool isValid() const;
inline bool isInputDevice() const;
inline bool isOutputDevice() const;

QString name() const;
Meep::DeviceType type() const;
Meep::DeviceInfo info() const;

QList<Meep::Device*> outputs() const;
QList<Meep::Device*> inputs() const;

Q_SIGNALS:

void inputAdded(Meep::Device*);
void inputRemoved(Meep::Device*);
void outputAdded(Meep::Device*);
void outputRemoved(Meep::Device*);
void receivedKeyPress(Meep::MidiKeyEvent*);
void receivedControlChange(Meep::MidiControlChangeEvent*);
void receivedProgramChange(Meep::MidiProgramChangeEvent*);
void receivedPitchChange(Meep::MidiPitchBendEvent*);

public slots:
void sendMidiEvent(Meep::MidiEvent*);
void sendKeyPress(Meep::MidiKeyEvent*);

void sendControlChange(Meep::MidiControlChangeEvent*);
void sendProgramChange(Meep::MidiProgramChangeEvent*);
void sendPitchChange(Meep::MidiPitchBendEvent*);
void sendCommand(unsigned long);

protected:

virtual void midiEvent(Meep::MidiEvent*);
};

As you can see, all different types of signals get emitted based on the MIDI event happening on the device. In case you are wondering, why I choose these events specifically, they are compliant to the MIDI standard. I tried to stay as compatible as possible and beside some MDI events, I have implemented all of them, so you should be able to use meep as your favorite MIDI library ;)

In case you want to use meep to route MIDI events from hardware to hardware, that is easily doable. The DeviceHandler has some nice and handy functions for this:

bool connect(Meep::Device* input, Meep::Device* output);
void disconnect(Meep::Device* input, Meep::Device* output);

So, all you need are two instantiated devices and then you can use them to build up routes. You can also connect one device to multiple targets, or multiple sources to on target. As the MIDI standard allows this, nothing should stop you in meep to do this. In the Software section I will provide some static binaries, simply take a look at the devicelogger example. That one allows you to connect a MIDI input with an output. I usually use it for connecting the MIDI keyboard with the Microsoft MIDI synthesizer, which is good enough for a quick play as my speakers are not of best quality anyway.

For completeness I think only one example is missing. What if you want to use MIDI all alone in software mode without any hardware? Well try the softsender example. It gives you a very easy GUI and allows you to play piano with your computer keyboard. It will use the Microsoft Software Synthesizer for this. The application then sends MIDI events to it and everything just works…

Softsender

 

In case you are interested, just feel free to download the source and play around with it. I am always opened for feedback.

You might wonder, whether there will be a linux of mac version of the library. I would really like to make that available, but I do not have access to develop on any Mac (well in theory in my company, but I have other things to do there :P ). And linux is complicated as always. I tried to get through the Alsa/Jack stuff, but even from a user perspective this is more than complex. So it might take some time until you will get some results from this frontier…

DeviceLogger

No Comments »

No comments yet.

RSS feed for comments on this post. | TrackBack URI

Leave a comment

XHTML ( You can use these tags):
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong> .