Diff for /np2/sound/vermouth/midiout.c between versions 1.12 and 1.13

version 1.12, 2005/03/29 06:50:38 version 1.13, 2006/12/10 11:14:31
Line 2 Line 2
 #include        "midiout.h"  #include        "midiout.h"
   
   
 #define MIDIOUT_VERSION         0x105  #define MIDIOUT_VERSION         0x115
 #define MIDIOUT_VERSTRING       "VERMOUTH 1.05"  #define MIDIOUT_VERSTRING       "VERMOUTH 1.15"
   
   static const char vermouthver[] = MIDIOUT_VERSTRING;
 static const OEMCHAR vermouthver[] = OEMTEXT(MIDIOUT_VERSTRING);  
   
 static const int gaintbl[24+1] =  static const int gaintbl[24+1] =
                                 { 16,  19,  22,  26,  32,  38,  45,  53,                                  { 16,  19,  22,  26,  32,  38,  45,  53,
Line 708  static void _allresetmidi(MIDIHDL midi) Line 707  static void _allresetmidi(MIDIHDL midi)
   
 // ----  // ----
   
 UINT midiout_getver(OEMCHAR *string, int leng) {  VEXTERN UINT VEXPORT midiout_getver(char *string, int leng) {
   
         milstr_ncpy(string, vermouthver, leng);          leng = min(leng, sizeof(vermouthver));
           CopyMemory(string, vermouthver, leng);
         return((MIDIOUT_VERSION << 8) | 0x00);          return((MIDIOUT_VERSION << 8) | 0x00);
 }  }
   
 MIDIHDL midiout_create(MIDIMOD module, UINT worksize) {  VEXTERN MIDIHDL VEXPORT midiout_create(MIDIMOD module, UINT worksize) {
   
         UINT    size;          UINT    size;
         MIDIHDL ret;          MIDIHDL ret;
Line 743  MIDIHDL midiout_create(MIDIMOD module, U Line 743  MIDIHDL midiout_create(MIDIMOD module, U
         return(ret);          return(ret);
 }  }
   
 void midiout_destroy(MIDIHDL hdl) {  VEXTERN void VEXPORT midiout_destroy(MIDIHDL hdl) {
   
         if (hdl) {          if (hdl) {
                 _MFREE(hdl);                  _MFREE(hdl);
         }          }
 }  }
   
 void midiout_shortmsg(MIDIHDL hdl, UINT32 msg) {  VEXTERN void VEXPORT midiout_shortmsg(MIDIHDL hdl, UINT32 msg) {
   
         UINT    cmd;          UINT    cmd;
         CHANNEL ch;          CHANNEL ch;
Line 803  void midiout_shortmsg(MIDIHDL hdl, UINT3 Line 803  void midiout_shortmsg(MIDIHDL hdl, UINT3
         }          }
 }  }
   
   static void longmsg_uni(MIDIHDL hdl, const UINT8 *msg, UINT size) {
   
           if ((size >= 6) && (msg[2] == 0x7f)) {
                   switch(msg[3]) {
                           case 0x04:
                                   if ((msg[4] == 0x01) && (size >= 8)) {
                                           hdl->master = msg[6] & 0x7f;
                                           allvolupdate(hdl);
                                   }
                                   break;
                   }
           }
   }
   
 static void longmsg_gm(MIDIHDL hdl, const UINT8 *msg, UINT size) {  static void longmsg_gm(MIDIHDL hdl, const UINT8 *msg, UINT size) {
   
         if ((size > 5) && (msg[2] == 0x7f) && (msg[3] == 0x09)) {          if ((size >= 6) && (msg[2] == 0x7f)) {
                 allresetmidi(hdl, FALSE);                                       // GM reset                  switch(msg[3]) {
                           case 0x09:
                                   if (msg[4] == 0x01) {
                                           allresetmidi(hdl, FALSE);                                       // GM reset
                                           break;
                                   }
   #if !defined(MIDI_GMONLY)
                                   else if ((msg[4] == 0x02) || (msg[4] == 0x03)) {
                                           allresetmidi(hdl, TRUE);                                        // GM reset
                                           break;
                                   }
   #endif
                                   break;
                   }
         }          }
 }  }
   
 static void longmsg_roland(MIDIHDL hdl, const UINT8 *msg, UINT size) {  static void rolandcmd4(MIDIHDL hdl, UINT addr, UINT8 data) {
   
         UINT    addr;  
         UINT8   data;  
         UINT    part;          UINT    part;
         CHANNEL ch;          CHANNEL ch;
 #if defined(ENABLE_GSRX)  #if defined(ENABLE_GSRX)
         UINT8   bit;          UINT8   bit;
 #endif  #endif
   
           addr = addr & 0x000fffff;
           if (addr == 0x00004) {                          // Vol
                   hdl->master = data;
                   allvolupdate(hdl);
           }
           else if ((addr & (~0xff)) == 0x00100) {
                   const UINT pos = addr & 0xff;
                   if (pos < 0x30) {               // Patch Name
                   }
                   else {
                           switch(addr & 0xff) {
                                   case 0x30:              // Reverb Macro
                                   case 0x31:              // Reverb Charactor
                                   case 0x32:              // Reverb Pre-LPF
                                   case 0x33:              // Reverb Level
                                   case 0x34:              // Reverb Time
                                   case 0x35:              // Reverb Delay FeedBack
                                   case 0x37:              // Reverb Predelay Time
                                   case 0x38:              // Chorus Macro
                                   case 0x39:              // Chorus Pre-LPF
                                   case 0x3a:              // Chorus Level
                                   case 0x3b:              // Chorus FeedBack
                                   case 0x3c:              // Chorus Delay
                                   case 0x3d:              // Chorus Rate
                                   case 0x3e:              // Chorus Depth
                                   case 0x3f:              // Chorus send level to reverb
                                   case 0x40:              // Chorus send level to delay
                                   case 0x50:              // Delay Macro
                                   case 0x51:              // Delay Time Pre-LPF
                                   case 0x52:              // Delay Time Center
                                   case 0x53:              // Delay Time Ratio Left
                                   case 0x54:              // Delay Time Ratio Right
                                   case 0x55:              // Delay Level Center
                                   case 0x56:              // Delay Level Left
                                   case 0x57:              // Delay Level Right
                                   case 0x58:              // Delay Level
                                   case 0x59:              // Delay Freeback
                                   case 0x5a:              // Delay sendlevel to Reverb
                                           break;
                           }
                   }
           }
           else if ((addr & (~(0x0fff))) == 0x01000) {     // GS CH
                   part = (addr >> 8) & 0x0f;
                   if (part == 0) {                                                // part10
                           part = 9;
                   }
                   else if (part < 10) {                                   // part1-9
                           part--;
                   }
                   ch = hdl->channel + part;
                   switch(addr & 0xff) {
   #if !defined(MIDI_GMONLY)
                           case 0x00:                                                      // TONE NUMBER
                                   ch->bank = data;
                                   break;
   #endif
   
                           case 0x01:                                                      // PROGRAM NUMBER
                                   progchange(hdl, ch, data);
                                   break;
   
                           case 0x02:                                                      // Rx.CHANNEL
                                   TRACEOUT(("RxCHANNEL: %d", data));
                                   break;
   
   #if defined(ENABLE_GSRX)
                           case 0x03:                                                      // Rx.PITCHBEND
                           case 0x04:                                                      // Rx.CH PRESSURE
                           case 0x05:                                                      // Rx.PROGRAM CHANGE
                           case 0x06:                                                      // Rx.CONTROL CHANGE
                           case 0x07:                                                      // Rx.POLY PRESSURE
                           case 0x08:                                                      // Rx.NOTE MESSAGE
                           case 0x09:                                                      // Rx.PRN
                           case 0x0a:                                                      // Rx.NRPN
                                   bit = 1 << ((addr - 0x03) & 7);
                                   if (data == 0) {
                                           ch->gsrx[0] = ch->gsrx[0] & (~bit);
                                   }
                                   else if (data == 1) {
                                           ch->gsrx[0] = ch->gsrx[0] | bit;
                                   }
                                   break;
   
                           case 0x0b:                                                      // Rx.MODULATION
                           case 0x0c:                                                      // Rx.VOLUME
                           case 0x0d:                                                      // Rx.PANPOT
                           case 0x0e:                                                      // Rx.EXPRESSION
                           case 0x0f:                                                      // Rx.HOLD1
                           case 0x10:                                                      // Rx.PORTAMENTO
                           case 0x11:                                                      // Rx.SOSTENUTO
                           case 0x12:                                                      // Rx.SOFT
                                   bit = 1 << ((addr - 0x0b) & 7);
                                   if (data == 0) {
                                           ch->gsrx[1] = ch->gsrx[1] & (~bit);
                                   }
                                   else if (data == 1) {
                                           ch->gsrx[1] = ch->gsrx[1] | bit;
                                   }
                                   break;
   #endif
                           case 0x15:                                                      // USE FOR RHYTHM PART
                                   if (data == 0) {
                                           ch->flag &= ~CHANNEL_RHYTHM;
                                           TRACEOUT(("ch%d - tone", part + 1));
                                   }
                                   else if ((data == 1) || (data == 2)) {
                                           ch->flag |= CHANNEL_RHYTHM;
                                           TRACEOUT(("ch%d - rhythm", part + 1));
                                   }
                                   break;
   
   #if defined(ENABLE_GSRX)
                           case 0x16:                                                      // PITCH KEY SHIFT
                                   if ((data >= 0x28) && (data <= 0x58)) {
                                           ch->keyshift = data;
                                   }
                                   break;
   
                           case 0x1d:                                                      // KEYBOARD RANGE LOW
                                   ch->noterange[0] = data;
                                   break;
   
                           case 0x1e:                                                      // KEYBOARD RANGE HIGH
                                   ch->noterange[1] = data;
                                   break;
   
                           case 0x23:                                                      // Rx.BANK SELECT
                           case 0x24:                                                      // Rx.BANK SELECT LSB
                                   bit = 1 << ((addr - 0x23) & 7);
                                   if (data == 0) {
                                           ch->gsrx[2] = ch->gsrx[2] & (~bit);
                                   }
                                   else if (data == 1) {
                                           ch->gsrx[2] = ch->gsrx[2] | bit;
                                   }
                                   break;
   #endif
                           default:
                                   TRACEOUT(("Roland GS - %.6x %.2x", addr, data));
                                   break;
                   }
           }
           else {
                   TRACEOUT(("Roland GS - %.6x %.2x", addr, data));
           }
   }
   
   static void longmsg_roland(MIDIHDL hdl, const UINT8 *msg, UINT size) {
   
           UINT    addr;
           UINT8   data;
   
         if (size <= 10) {          if (size <= 10) {
                 return;                  return;
         }          }
Line 837  static void longmsg_roland(MIDIHDL hdl,  Line 1015  static void longmsg_roland(MIDIHDL hdl, 
                         allresetmidi(hdl, TRUE);                          allresetmidi(hdl, TRUE);
                         TRACEOUT(("GS-Reset"));                          TRACEOUT(("GS-Reset"));
                 }                  }
                 else if (addr == 0x400004) {                            // Vol                  else if ((addr & 0xfff00000) == 0x00400000) {
                         hdl->master = data;                          rolandcmd4(hdl, addr, data);
                         allvolupdate(hdl);  
                 }  
                 else if ((addr & (~(0x000fff))) == 0x401000) {  // GS CH  
                         part = (addr >> 8) & 0x0f;  
                         if (part == 0) {                                                // part10  
                                 part = 9;  
                         }  
                         else if (part < 10) {                                   // part1-9  
                                 part--;  
                         }  
                         ch = hdl->channel + part;  
                         switch(addr & 0xff) {  
 #if !defined(MIDI_GMONLY)  
                                 case 0x00:                                                      // TONE NUMBER  
                                         ch->bank = data;  
                                         break;  
 #endif  
   
                                 case 0x01:                                                      // PROGRAM NUMBER  
                                         progchange(hdl, ch, data);  
                                         break;  
   
 #if defined(ENABLE_GSRX)  
                                 case 0x03:                                                      // Rx.PITCHBEND  
                                 case 0x04:                                                      // Rx.CH PRESSURE  
                                 case 0x05:                                                      // Rx.PROGRAM CHANGE  
                                 case 0x06:                                                      // Rx.CONTROL CHANGE  
                                 case 0x07:                                                      // Rx.POLY PRESSURE  
                                 case 0x08:                                                      // Rx.NOTE MESSAGE  
                                 case 0x09:                                                      // Rx.PRN  
                                 case 0x0a:                                                      // Rx.NRPN  
                                         bit = 1 << ((addr - 0x03) & 7);  
                                         if (data == 0) {  
                                                 ch->gsrx[0] = ch->gsrx[0] & (~bit);  
                                         }  
                                         else if (data == 1) {  
                                                 ch->gsrx[0] = ch->gsrx[0] | bit;  
                                         }  
                                         break;  
   
                                 case 0x0b:                                                      // Rx.MODULATION  
                                 case 0x0c:                                                      // Rx.VOLUME  
                                 case 0x0d:                                                      // Rx.PANPOT  
                                 case 0x0e:                                                      // Rx.EXPRESSION  
                                 case 0x0f:                                                      // Rx.HOLD1  
                                 case 0x10:                                                      // Rx.PORTAMENTO  
                                 case 0x11:                                                      // Rx.SOSTENUTO  
                                 case 0x12:                                                      // Rx.SOFT  
                                         bit = 1 << ((addr - 0x0b) & 7);  
                                         if (data == 0) {  
                                                 ch->gsrx[1] = ch->gsrx[1] & (~bit);  
                                         }  
                                         else if (data == 1) {  
                                                 ch->gsrx[1] = ch->gsrx[1] | bit;  
                                         }  
                                         break;  
 #endif  
                                 case 0x15:                                                      // USE FOR RHYTHM PART  
                                         if (data == 0) {  
                                                 ch->flag &= ~CHANNEL_RHYTHM;  
                                                 TRACEOUT(("ch%d - tone", part + 1));  
                                         }  
                                         else if ((data == 1) || (data == 2)) {  
                                                 ch->flag |= CHANNEL_RHYTHM;  
                                                 TRACEOUT(("ch%d - rhythm", part + 1));  
                                         }  
                                         break;  
   
 #if defined(ENABLE_GSRX)  
                                 case 0x16:                                                      // PITCH KEY SHIFT  
                                         if ((data >= 0x28) && (data <= 0x58)) {  
                                                 ch->keyshift = data;  
                                         }  
                                         break;  
   
                                 case 0x1d:                                                      // KEYBOARD RANGE LOW  
                                         ch->noterange[0] = data;  
                                         break;  
   
                                 case 0x1e:                                                      // KEYBOARD RANGE HIGH  
                                         ch->noterange[1] = data;  
                                         break;  
   
                                 case 0x23:                                                      // Rx.BANK SELECT  
                                 case 0x24:                                                      // Rx.BANK SELECT LSB  
                                         bit = 1 << ((addr - 0x23) & 7);  
                                         if (data == 0) {  
                                                 ch->gsrx[2] = ch->gsrx[2] & (~bit);  
                                         }  
                                         else if (data == 1) {  
                                                 ch->gsrx[2] = ch->gsrx[2] | bit;  
                                         }  
                                         break;  
 #endif  
                                 default:  
                                         TRACEOUT(("Roland GS - %.6x", addr));  
                                         break;  
                         }  
                 }                  }
                 else {  #if defined(ENABLE_PORTB)
                         TRACEOUT(("Roland GS - %.6x", addr));                  else if ((addr & 0xfff00000) == 0x00500000) {
                           if (hdl->portb) {
                                   rolandcmd4(hdl->portb, addr, data);
                           }
                 }                  }
   #endif  // defined(ENABLE_PORTB)
                 addr++;                  addr++;
         }          }
 }  }
   
 void midiout_longmsg(MIDIHDL hdl, const UINT8 *msg, UINT size) {  VEXTERN void VEXPORT midiout_longmsg(MIDIHDL hdl, const UINT8 *msg, UINT size) {
   
         UINT    id;          UINT    id;
   
Line 954  void midiout_longmsg(MIDIHDL hdl, const  Line 1038  void midiout_longmsg(MIDIHDL hdl, const 
         }          }
         if (size > 3) {                                                 // (msg[size - 1] == 0xf7)          if (size > 3) {                                                 // (msg[size - 1] == 0xf7)
                 id = msg[1];                  id = msg[1];
                 if (id == 0x7e) {                                       // GM                  if (id == 0x7f) {                                       // Universal realtime
                           longmsg_uni(hdl, msg, size);
                   }
                   else if (id == 0x7e) {                          // GM
                         longmsg_gm(hdl, msg, size);                          longmsg_gm(hdl, msg, size);
                 }                  }
                 else if (id == 0x41) {                          // Roland                  else if (id == 0x41) {                          // Roland
                         longmsg_roland(hdl, msg, size);                          longmsg_roland(hdl, msg, size);
                 }                  }
                   else {
                           TRACEOUT(("long msg unknown id:%02x", id));
                   }
         }          }
 }  }
   
 const SINT32 *midiout_get(MIDIHDL hdl, UINT *samples) {  VEXTERN const SINT32 * VEXPORT midiout_get(MIDIHDL hdl, UINT *samples) {
   
         UINT    size;          UINT    size;
         VOICE   v;          VOICE   v;
Line 1036  moget_err: Line 1126  moget_err:
         return(NULL);          return(NULL);
 }  }
   
 UINT midiout_get32(MIDIHDL hdl, SINT32 *pcm, UINT size) {  VEXTERN UINT VEXPORT midiout_get16(MIDIHDL hdl, SINT16 *pcm, UINT size) {
   
           UINT    step;
           VOICE   v;
           VOICE   vterm;
           SINT32  *buf;
           SAMPLE  src;
           SAMPLE  srcterm;
           UINT    cnt;
           UINT    pos;
           UINT    rem;
           SINT32  l;
           SINT32  r;
   
           if ((hdl != NULL) && (size)) {
                   do {
                           step = min(size, hdl->worksize);
                           size -= step;
                           buf = hdl->sampbuf;
                           ZeroMemory(buf, step * 2 * sizeof(SINT32));
                           v = hdl->voice;
                           vterm = v + VOICE_MAX;
                           do {
                                   if (v->phase != VOICE_FREE) {
                                           cnt = step;
                                           if (v->phase & VOICE_REL) {
                                                   voice_setfree(v);
                                                   if (cnt > REL_COUNT) {
                                                           cnt = REL_COUNT;
                                                   }
                                           }
                                           if (v->flag & VOICE_FIXPITCH) {
                                                   pos = v->samppos >> FREQ_SHIFT;
                                                   src = v->sample->data + pos;
                                                   rem = (v->sample->datasize >> FREQ_SHIFT) - pos;
                                                   if (cnt < rem) {
                                                           v->samppos += cnt << FREQ_SHIFT;
                                                           srcterm = src + cnt;
                                                   }
                                                   else {
                                                           voice_setfree(v);
                                                           srcterm = src + rem;
                                                   }
                                           }
                                           else {
                                                   src = hdl->resampbuf;
                                                   srcterm = v->resamp(v, src, src + cnt);
                                           }
                                           if (src != srcterm) {
                                                   v->mix(v, buf, src, srcterm);
                                           }
                                   }
                                   v++;
                           } while(v < vterm);
                           do {
                                   l = pcm[0];
                                   r = pcm[1];
                                   l += buf[0] >> (SAMP_SHIFT + 1);
                                   r += buf[1] >> (SAMP_SHIFT + 1);
                                   if (l < -32768) {
                                           l = -32768;
                                   }
                                   else if (l > 32767) {
                                           l = 32767;
                                   }
                                   if (r < -32768) {
                                           r = -32768;
                                   }
                                   else if (r > 32767) {
                                           r = 32767;
                                   }
                                   pcm[0] = l;
                                   pcm[1] = r;
                                   buf += 2;
                                   pcm += 2;
                           } while(--step);
                   } while(size);
           }
           return(0);}
   
   VEXTERN UINT VEXPORT midiout_get32(MIDIHDL hdl, SINT32 *pcm, UINT size) {
   
         UINT    step;          UINT    step;
         VOICE   v;          VOICE   v;
Line 1099  UINT midiout_get32(MIDIHDL hdl, SINT32 * Line 1269  UINT midiout_get32(MIDIHDL hdl, SINT32 *
         return(0);          return(0);
 }  }
   
 void midiout_setgain(MIDIHDL hdl, int gain) {  VEXTERN void VEXPORT midiout_setgain(MIDIHDL hdl, int gain) {
   
         if (hdl) {          if (hdl) {
                 if (gain < -16) {                  if (gain < -16) {
Line 1113  void midiout_setgain(MIDIHDL hdl, int ga Line 1283  void midiout_setgain(MIDIHDL hdl, int ga
         }          }
 }  }
   
   VEXTERN void VEXPORT midiout_setmoduleid(MIDIHDL hdl, UINT8 moduleid) {
   
           if (hdl) {
                   hdl->moduleid = moduleid;
           }
   }
   
   VEXTERN void VEXPORT midiout_setportb(MIDIHDL hdl, MIDIHDL portb) {
   
   #if defined(ENABLE_PORTB)
           if (hdl) {
                   hdl->portb = portb;
           }
   #endif  // defined(ENABLE_PORTB)
   }
   

Removed from v.1.12  
changed lines
  Added in v.1.13


RetroPC.NET-CVS <cvs@retropc.net>