[BACK]Return to midi.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / aucat

Diff for /src/usr.bin/aucat/Attic/midi.c between version 1.2 and 1.3

version 1.2, 2009/08/19 05:54:15 version 1.3, 2009/08/21 16:48:03
Line 29 
Line 29 
 #include <stdlib.h>  #include <stdlib.h>
 #include <string.h>  #include <string.h>
   
 #include "conf.h"  
 #include "abuf.h"  #include "abuf.h"
 #include "aproc.h"  #include "aproc.h"
   #include "conf.h"
   #include "dev.h"
 #include "midi.h"  #include "midi.h"
   
 /*  /*
Line 41 
Line 42 
 #define MIDITHRU_XFER 340  #define MIDITHRU_XFER 340
 #define MIDITHRU_TIMO 100000  #define MIDITHRU_TIMO 100000
   
   /*
    * masks to extract command and channel of status byte
    */
   #define MIDI_CMDMASK    0xf0
   #define MIDI_CHANMASK   0x0f
   
   /*
    * MIDI status bytes of voice messages
    */
   #define MIDI_NOFF       0x80            /* note off */
   #define MIDI_NON        0x90            /* note on */
   #define MIDI_KAT        0xa0            /* key after touch */
   #define MIDI_CTL        0xb0            /* controller */
   #define MIDI_PC         0xc0            /* program change */
   #define MIDI_CAT        0xd0            /* channel after touch */
   #define MIDI_BEND       0xe0            /* pitch bend */
   
   /*
    * MIDI controller numbers
    */
   #define MIDI_CTLVOL     7               /* volume */
   #define MIDI_CTLPAN     11              /* pan */
   
   /*
    * length of voice and common messages (status byte included)
    */
 unsigned voice_len[] = { 3, 3, 3, 3, 2, 2, 3 };  unsigned voice_len[] = { 3, 3, 3, 3, 2, 2, 3 };
 unsigned common_len[] = { 0, 2, 3, 2, 0, 0, 1, 1 };  unsigned common_len[] = { 0, 2, 3, 2, 0, 0, 1, 1 };
   
Line 263 
Line 290 
         p->u.thru.owner = NULL;          p->u.thru.owner = NULL;
         timo_set(&p->u.thru.timo, thru_cb, p);          timo_set(&p->u.thru.timo, thru_cb, p);
         timo_add(&p->u.thru.timo, MIDITHRU_TIMO);          timo_add(&p->u.thru.timo, MIDITHRU_TIMO);
           return p;
   }
   
   void
   ctl_sendmsg(struct aproc *p, struct abuf *ibuf, unsigned char *msg, unsigned len)
   {
           unsigned ocount, itodo;
           unsigned char *odata, *idata;
           struct abuf *i, *inext;
   
           for (i = LIST_FIRST(&p->obuflist); i != NULL; i = inext) {
                   inext = LIST_NEXT(i, oent);
                   if (i->duplex == ibuf)
                           continue;
                   itodo = len;
                   idata = msg;
                   while (itodo > 0) {
                           if (!ABUF_WOK(i)) {
                                   DPRINTFN(2, "ctl_sendmsg: lost %u\n", i->used);
                                   abuf_rdiscard(i, i->used);
                           }
                           odata = abuf_wgetblk(i, &ocount, 0);
                           if (ocount > itodo)
                                   ocount = itodo;
                           DPRINTFN(2, "ctl_sendmsg: xfer %u\n", ocount);
                           memcpy(odata, idata, ocount);
                           abuf_wcommit(i, ocount);
                           itodo -= ocount;
                           idata += ocount;
                   }
                   (void)abuf_flush(i);
           }
   }
   
   int
   ctl_slotnew(struct aproc *p, char *name, struct aproc *owner)
   {
           char *s;
           int index, i;
           struct ctl_slot *slot;
   
           DPRINTF("ctl_newslot: called by %s \"%s\"\n", owner->name, name);
           for (index = 0, slot = p->u.ctl.slot; ; index++, slot++) {
                   if (index == CTL_NSLOT)
                           return -1;
                   if (slot->owner == NULL)
                           break;
           }
           for (i = 0, s = name; ; s++) {
                   if (i == CTL_NAMEMAX - 1 || *s == '\0') {
                           break;
                   } else if (*s >= 'A' && *s <= 'Z') {
                           slot->name[i++] = *s + 'a' - 'A';
                   } else if (*s >= 'a' || *s <= 'z')
                           slot->name[i++] = *s;
           }
           if (i == 0)
                   strlcpy(slot->name, "noname", CTL_NAMEMAX);
           else
                   slot->name[i] = '\0';
           slot->owner = owner;
           slot->unit = index;
           DPRINTFN(1, "ctl_newslot: %s%u\n", slot->name, slot->unit);
           return index;
   }
   
   void
   ctl_slotdel(struct aproc *p, int index)
   {
           p->u.ctl.slot[index].owner = NULL;
   }
   
   void
   ctl_slotvol(struct aproc *p, int slot, unsigned vol)
   {
           unsigned char msg[3];
   
           DPRINTFN(1, "ctl_slotvol: [%u] -> %u\n", slot, vol);
           msg[0] = MIDI_CTL | slot;
           msg[1] = MIDI_CTLVOL;
           msg[2] = vol;
           ctl_sendmsg(p, NULL, msg, 3);
   }
   
   void
   ctl_ev(struct aproc *p, struct abuf *ibuf)
   {
           unsigned i;
           unsigned chan;
           struct aproc *owner;
   
   #ifdef DEBUG
           if (debug_level > 0) {
                   fprintf(stderr, "ctl_ev:");
                   for (i = 0; i < ibuf->mlen; i++)
                           fprintf(stderr, " %02x", ibuf->mdata[i]);
                   fprintf(stderr, "\n");
           }
   #endif
           if ((ibuf->mdata[0] & MIDI_CMDMASK) == MIDI_CTL &&
               ibuf->mdata[1] == MIDI_CTLVOL) {
                   chan = ibuf->mdata[0] & MIDI_CHANMASK;
                   if (chan >= CTL_NSLOT)
                           return;
                   owner = p->u.ctl.slot[chan].owner;
                   if (owner == NULL || LIST_EMPTY(&owner->obuflist))
                           return;
                   dev_setvol(
                       LIST_FIRST(&owner->obuflist),
                       MIDI_TO_ADATA(ibuf->mdata[2]));
                   ctl_sendmsg(p, ibuf, ibuf->mdata, ibuf->mlen);
           }
   }
   
   int
   ctl_in(struct aproc *p, struct abuf *ibuf)
   {
           unsigned char *idata;
           unsigned c, i, icount;
   
           if (!ABUF_ROK(ibuf))
                   return 0;
           idata = abuf_rgetblk(ibuf, &icount, 0);
           for (i = 0; i < icount; i++) {
                   c = *idata++;
                   if (c >= 0xf0) {
                           /* clock and common events not used yet */
                   } else if (c >= 0x80) {
                           ibuf->mdata[0] = c;
                           ibuf->mlen = voice_len[(c >> 4) & 7];
                           ibuf->mstatus = c;
                           ibuf->mindex = 1;
                   } else if (ibuf->mstatus) {
                           if (ibuf->mindex == 0)
                                   ibuf->mdata[ibuf->mindex++] = ibuf->mstatus;
                           ibuf->mdata[ibuf->mindex++] = c;
                           if (ibuf->mindex == ibuf->mlen) {
                                   ctl_ev(p, ibuf);
                                   ibuf->mindex = 0;
                           }
                   }
           }
           abuf_rdiscard(ibuf, icount);
           return 1;
   }
   
   int
   ctl_out(struct aproc *p, struct abuf *obuf)
   {
           return 0;
   }
   
   void
   ctl_eof(struct aproc *p, struct abuf *ibuf)
   {
           DPRINTF("ctl_eof: %s: eof\n", p->name);
   }
   
   void
   ctl_hup(struct aproc *p, struct abuf *obuf)
   {
           DPRINTF("ctl_hup: %s: detached\n", p->name);
   }
   
   void
   ctl_newin(struct aproc *p, struct abuf *ibuf)
   {
           ibuf->mused = 0;
           ibuf->mlen = 0;
           ibuf->mindex = 0;
           ibuf->mstatus = 0;
   }
   
   void
   ctl_done(struct aproc *p)
   {
           unsigned i;
           struct ctl_slot *s;
   
           for (i = 0, s = p->u.ctl.slot; i < CTL_NSLOT; i++, s++) {
                   if (s->owner)
                           DPRINTF("ctl_done: %s%u not freed\n", s->name, s->unit);
           }
   }
   
   struct aproc_ops ctl_ops = {
           "ctl",
           ctl_in,
           ctl_out,
           ctl_eof,
           ctl_hup,
           ctl_newin,
           NULL, /* newout */
           NULL, /* ipos */
           NULL, /* opos */
           ctl_done
   };
   
   struct aproc *
   ctl_new(char *name)
   {
           struct aproc *p;
           unsigned i;
   
           p = aproc_new(&ctl_ops, name);
           for (i = 0; i < CTL_NSLOT; i++) {
                   p->u.ctl.slot[i].unit = i;
                   p->u.ctl.slot[i].owner = NULL;
                   strlcpy(p->u.ctl.slot[i].name, "unknown", CTL_NAMEMAX);
           }
         return p;          return p;
 }  }
   

Legend:
Removed from v.1.2  
changed lines
  Added in v.1.3