Hi,
On Thursday 05 January 2012, Dave Stikkolorum wrote:
Hi all,
I try to write a c program that sends midi notes to the Hydrogen drum
sequencer.
I use the alsa library to create a client with an output port.
I attached two files.
loopqueue.c works but loop.c doesn't.
A base drum (note:28) is being send.
I am not succeeding to use direct delivery,
but it only works with the queue.
Any ideas why?
In both programs you need to connect the output port to some input port (for
instance, a soft synth). To do so, you can insert a call to
snd_seq_connect_to() after creating your port:
snd_seq_connect_to(seq, port, 20, 0);
Where 20:0 are the client:port numbers of the receiving port.
The problem in loop.c is that you are using the function snd_seq_ev_set_note()
that includes a duration as the 5th parameter. This function will create two
MIDI events in a queue, the first one will be the noteon event, and the second
one will be a noteoff event, scheduled adding the specified duration to the
start time of the former noteon event. That requires a queue for event
scheduling.
If you don't mind about noteoff events, because most percussion synths don't
bother about them anyway, replace that function call by
snd_seq_ev_set_noteon(). There is also a snd_seq_ev_set_noteoff() function as
well.
You may be interested in my C++/Qt4 wrapper around the ALSA sequencer API:
http://drumstick.sourceforge.net/docs/index.html
Here is how a simple program playing a note-on MIDI message using drumstick
looks like:
#include <QApplication>
#include <drumstick.h>
int main(int argc, char **argv) {
QApplication app(argc, argv, false);
// create a client object on the heap
drumstick::MidiClient *client = new drumstick::MidiClient;
client->open();
client->setClientName( "MyClient" );
// create the port
drumstick::MidiPort *port = client->createPort();
port->setPortName( "MyPort" );
port->setCapability( SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ );
port->setPortType( SND_SEQ_PORT_TYPE_MIDI_GENERIC );
// subscribe the port to some other client:port
port->subscribeTo( "20:0" ); // or "name:port", like in
"KMidimon:0"
// create an event object on the stack, to send a note on message
drumstick::NoteOnEvent ev( 0, 66, 100 );
ev.setSource( port->getPortId() );
ev.setSubscribers(); // deliver to all the connected ports
ev.setDirect(); // not scheduled, deliver immediately
client->output( &ev ); // or outputDirect() if you prefer not buffered
client->drainOutput(); // flush the buffer
// close and clean
client->close();
delete client;
return 0;
}
One program that uses Drumstick to play metronome and drum patterns is
KMetronome:
http://kmetronome.sourceforge.net/kmetronome.shtml
Regards,
Pedro