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

Diff for /src/usr.bin/sndiod/midi.c between version 1.1 and 1.2

version 1.1, 2012/11/23 07:03:28 version 1.2, 2012/11/30 20:30:24
Line 60 
Line 60 
 unsigned int midi_portnum = 0;  unsigned int midi_portnum = 0;
   
 struct midithru {  struct midithru {
         unsigned txmask;          unsigned int txmask, rxmask;
 #define MIDITHRU_NMAX 32  #define MIDITHRU_NMAX 32
 } midithru[MIDITHRU_NMAX];  } midithru[MIDITHRU_NMAX];
   
Line 120 
Line 120 
         ep->idx = 0;          ep->idx = 0;
         ep->st = 0;          ep->st = 0;
         ep->txmask = 0;          ep->txmask = 0;
         ep->rxmask = 1 << i;          ep->self = 1 << i;
           ep->tickets = 0;
         ep->mode = mode;          ep->mode = mode;
   
         /*          /*
          * client output is our input (ibuf) and our output (obuf) goes           * the output buffer is the client intput
          * to client input  
          */           */
         if (ep->mode & MODE_MIDIOUT) {          if (ep->mode & MODE_MIDIIN)
                 abuf_init(&ep->ibuf, MIDI_BUFSZ);  
         }  
         if (ep->mode & MODE_MIDIIN) {  
                 abuf_init(&ep->obuf, MIDI_BUFSZ);                  abuf_init(&ep->obuf, MIDI_BUFSZ);
         }          midi_tickets(ep);
         return ep;          return ep;
 }  }
   
Line 139 
Line 137 
 midi_del(struct midi *ep)  midi_del(struct midi *ep)
 {  {
         int i;          int i;
           struct midi *peer;
   
         for (i = 0; i < MIDI_NEP; i++)          ep->txmask = 0;
                 midi_ep[i].txmask &= ~ep->rxmask;          for (i = 0; i < MIDI_NEP; i++) {
         for (i = 0; i < MIDITHRU_NMAX; i++)                  peer = midi_ep + i;
                 midithru[i].txmask &= ~ep->rxmask;                  if (peer->txmask & ep->self) {
                           peer->txmask &= ~ep->self;
         /* XXX: drain output */                          midi_tickets(peer);
         ep->ops = NULL;                  }
         if (ep->mode & MODE_MIDIOUT) {  
                 abuf_done(&ep->ibuf);  
         }          }
           for (i = 0; i < MIDITHRU_NMAX; i++) {
                   midithru[i].txmask &= ~ep->self;
                   midithru[i].rxmask &= ~ep->self;
           }
           ep->ops = NULL;
         if (ep->mode & MODE_MIDIIN) {          if (ep->mode & MODE_MIDIIN) {
                 abuf_done(&ep->obuf);                  abuf_done(&ep->obuf);
         }          }
 }  }
   
 /*  /*
  * add the midi endpoint in the ``tag'' midi thru box   * connect two midi endpoints
  */   */
 void  void
 midi_tag(struct midi *ep, unsigned int tag)  midi_link(struct midi *ep, struct midi *peer)
 {  {
         int i;          if (ep->mode & MODE_MIDIOUT) {
         struct midi *m;                  ep->txmask |= peer->self;
         unsigned members;                  midi_tickets(ep);
   
         members = midithru[tag].txmask;  
         midithru[tag].txmask |= ep->rxmask;  
   
         for (i = 0, m = midi_ep; i < MIDI_NEP; i++, m++) {  
                 if (!(members & (1 << i)))  
                         continue;  
                 if (ep->mode & MODE_MIDIOUT)  
                         ep->txmask |= m->rxmask;  
                 if (ep->mode & MODE_MIDIIN)  
                         m->txmask |= ep->rxmask;  
         }          }
           if (ep->mode & MODE_MIDIIN) {
   #ifdef DEBUG
                   if (ep->obuf.used > 0) {
                           midi_log(ep);
                           log_puts(": linked with non-empty buffer\n");
                           panic();
                   }
   #endif
                   /* ep has empry buffer, so no need to call midi_tickets() */
                   peer->txmask |= ep->self;
           }
 }  }
   
 /*  /*
  * remove the midi endpoint from the ``tag'' midi thru box   * add the midi endpoint in the ``tag'' midi thru box
  */   */
 void  void
 midi_untag(struct midi *ep, unsigned int tag)  midi_tag(struct midi *ep, unsigned int tag)
 {  {
           struct midi *peer;
           struct midithru *t = midithru + tag;
         int i;          int i;
         struct midi *m;  
         unsigned members;  
   
         members = midithru[tag].txmask;          if (ep->mode & MODE_MIDIOUT) {
         midithru[tag].txmask &= ~ep->rxmask;                  ep->txmask |= t->txmask;
                   midi_tickets(ep);
         for (i = 0, m = midi_ep;; i++, m++) {  
                 if (!(members & (1 << i)))  
                         continue;  
                 ep->txmask &= ~m->rxmask;  
                 m->txmask &= ~ep->rxmask;  
         }          }
           if (ep->mode & MODE_MIDIIN) {
   #ifdef DEBUG
                   if (ep->obuf.used > 0) {
                           midi_log(ep);
                           log_puts(": tagged with non-empty buffer\n");
                           panic();
                   }
   #endif
                   for (i = 0; i < MIDI_NEP; i++) {
                           if (!(t->rxmask & (1 << i)))
                                   continue;
                           peer = midi_ep + i;
                           peer->txmask |= ep->self;
                   }
           }
           if (ep->mode & MODE_MIDIOUT)
                   t->rxmask |= ep->self;
           if (ep->mode & MODE_MIDIIN)
                   t->txmask |= ep->self;
 }  }
   
 /*  /*
Line 241 
Line 257 
 }  }
   
   
   /*
    * determine if we have gained more input tickets, and if so call the
    * fill() call-back to notify the i/o layer that it can send more data
    */
 void  void
 midi_fill(struct midi *oep)  midi_tickets(struct midi *iep)
 {  {
         int i, count;          int i, tickets, avail, maxavail;
         struct midi *iep;          struct midi *oep;
   
           maxavail = MIDI_BUFSZ;
         for (i = 0; i < MIDI_NEP ; i++) {          for (i = 0; i < MIDI_NEP ; i++) {
                 if ((oep->rxmask & (1 << i)) == 0)                  if ((iep->txmask & (1 << i)) == 0)
                         continue;                          continue;
                   oep = midi_ep + i;
                   avail = oep->obuf.len - oep->obuf.used;
                   if (maxavail > avail)
                           maxavail = avail;
           }
   
           /*
            * in the worst case output message is twice the
            * input message (2-byte messages with running status)
            */
           tickets = maxavail / 2 - iep->tickets;
           if (tickets > 0) {
                   iep->tickets += tickets;
                   iep->ops->fill(iep->arg, tickets);
           }
   }
   
   /*
    * recalculate tickets of endpoints sending data to this one
    */
   void
   midi_fill(struct midi *oep)
   {
           int i;
           struct midi *iep;
   
           for (i = 0; i < MIDI_NEP; i++) {
                 iep = midi_ep + i;                  iep = midi_ep + i;
                 count = midi_in(iep);                  if (iep->txmask & oep->self)
                 if (count)                          midi_tickets(iep);
                         iep->ops->fill(iep->arg, count);  
         }          }
 }  }
   
 /*  /*
  * parse the give data chunk, and calling imsg() for each message   * parse then give data chunk, and calling imsg() for each message
  */   */
 void  void
 midi_parse(struct midi *iep, unsigned char *idata, int icount)  midi_in(struct midi *iep, unsigned char *idata, int icount)
 {  {
         int i;          int i;
         unsigned char c;          unsigned char c;
Line 304 
Line 351 
                         }                          }
                 }                  }
         }          }
           iep->tickets -= icount;
           if (iep->tickets < 0)
                   iep->tickets = 0;
 }  }
   
 /*  /*
  * process input data stored in ep->ibuf  
  */  
 int  
 midi_in(struct midi *iep)  
 {  
         unsigned char *idata;  
         int i, icount, maxavail, avail, idone;  
         struct midi *oep;  
   
         /*  
          * calculate the max message size we can process  
          */  
         maxavail = MIDI_BUFSZ;  
         for (i = 0; i < MIDI_NEP ; i++) {  
                 if ((iep->txmask & (1 << i)) == 0)  
                         continue;  
                 oep = midi_ep + i;  
                 avail = oep->obuf.len - oep->obuf.used;  
                 if (maxavail > avail)  
                         maxavail = avail;  
         }  
   
         /*  
          * in the works case output message is twice the  
          * input message (2-byte messages with running status)  
          */  
         maxavail /= 2;  
         idone = 0;  
         for (;;) {  
                 idata = abuf_rgetblk(&iep->ibuf, &icount);  
                 if (icount > maxavail)  
                         icount = maxavail;  
                 if (icount == 0)  
                         break;  
                 maxavail -= icount;  
 #ifdef DEBUG  
                 if (log_level >= 4) {  
                         midi_log(iep);  
                         log_puts(":  in:");  
                         for (i = 0; i < icount; i++) {  
                                 log_puts(" ");  
                                 log_putx(idata[i]);  
                         }  
                         log_puts("\n");  
                 }  
 #endif  
                 midi_parse(iep, idata, icount);  
                 abuf_rdiscard(&iep->ibuf, icount);  
                 idone += icount;  
         }  
         return idone;  
 }  
   
 /*  
  * store the given message in the output buffer   * store the given message in the output buffer
  */   */
 void  void
Line 377 
Line 373 
 #ifdef DEBUG  #ifdef DEBUG
                         if (log_level >= 2) {                          if (log_level >= 2) {
                                 midi_log(oep);                                  midi_log(oep);
                                 log_puts(": overrun, discarding ");                                  log_puts(": too slow, discarding ");
                                 log_putu(oep->obuf.used);                                  log_putu(oep->obuf.used);
                                 log_puts(" bytes\n");                                  log_puts(" bytes\n");
                         }                          }

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