/******************************************************************
* I am trying to understand midi programming on linux using
* the /dev/music API. My main source of info is the
* "Open Sound System(tm) Programmer's Guide" version 1.1 from
* 4Front Technologies and the playmidi source code.
*
* I have written python bindings for the needed macros, but
* I use a C example here because eliminate all the bugs in the
* python bindings.
*
* I use the /dev/music API instead of /dev/sequencer because
* that is the recommendation from the Programmer's Guide.
* Does anyone know when (what kernel version) the /dev/music
* api was first introduced?
*
* My problem is understanding channels.
* I want to use channel 0 for clarinet and channel 1 for oboe.
* This works ok as long as the first note entered is in channel
* 0.
*
* But if the first note is in oboe, channel 1, like in the example
* below, then the clarinet note does not stop when it is supposed
* to do. You could say the obvious is to reorder the two lines
* containing SET_START_NOTE, but that is not the question here.
* My mudela-like parser don't want to do that!
*
* What have I misunderstood? The programmers guide does not mention
* that you have to use channel 0 before channel 1. Is this a bug in
* OSS, the documentation or (most probably) my code???
*
* Thanks in advance,
*
* Tom Cato
**/
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h> /* for writing to the device */
#include <sys/soundcard.h> /* the soundcard macro definitions */
#include <assert.h>
int seqfd = -1; /* file descriptor for /dev/music */
SEQ_DEFINEBUF(2048);
void seqbuf_dump() /* the MIDI messages get dumped here */
{
assert(seqfd != -1);
if (_seqbufptr)
if (write (seqfd, _seqbuf, _seqbufptr) == -1)
perror("Can't write to MIDI device");
_seqbufptr = 0;
}
/* return 1 if successful, 0 if fail */
int sndctl_seq_reset()
{
if (ioctl(seqfd, SNDCTL_SEQ_RESET) != 0) {
perror("solfege_c_midi.sndctl_seq_reset");
return 0;
}
return 1;
}
int main() {
int devnum = 0;
printf("Test av midi\n");
seqfd = open("/dev/music", O_WRONLY, 0);
sndctl_seq_reset();
SEQ_START_TIMER();
SEQ_SET_PATCH(devnum, 1, 71); /* Clarinet */
SEQ_SET_PATCH(devnum, 0, 68); /* Oboe */
/* The next three lines is a workaround that make the clarinet
* tone stop when it is supposed. Note that using volume 0 does
* not help, it has to be 1 or greater. */
/*
SEQ_START_NOTE(devnum, 0, 50, 1);
SEQ_DELTA_TIME(0);
SEQ_STOP_NOTE(devnum, 0, 50, 1);
*/
SEQ_START_NOTE(devnum, 1, 58, 100);
SEQ_START_NOTE(devnum, 0, 61, 100);
SEQ_DELTA_TIME(96);
SEQ_STOP_NOTE (devnum, 1, 58, 100);
SEQ_STOP_NOTE (devnum, 0, 61, 100);
SEQ_STOP_TIMER();
seqbuf_dump();
getchar();
close(seqfd);
return 0;
}
--
Tom Cato Amundsen <[EMAIL PROTECTED]>
GNU Solfege - free eartraining, http://www.gnu.org/software/solfege/
_______________________________________________
Gnu-music-discuss mailing list
[EMAIL PROTECTED]
http://mail.gnu.org/mailman/listinfo/gnu-music-discuss