gnu-music-discuss
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

/dev/music programming question


From: Tom Cato Amundsen
Subject: /dev/music programming question
Date: Fri, 10 Nov 2000 17:45:27 +0100
User-agent: Mutt/1.2.5i

/******************************************************************
 * 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 <address@hidden>
GNU Solfege - free eartraining, http://www.gnu.org/software/solfege/



reply via email to

[Prev in Thread] Current Thread [Next in Thread]