亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關(guān)于我們
? 蟲蟲下載站

?? lkeymidi.cpp

?? ldraw_DOS游戲開發(fā)包
?? CPP
?? 第 1 頁 / 共 4 頁
字號(hào):
/**************************************************************************
 *  LinDevelop v1.2
 *  The core MIDI file player.
 *  written by Lin Wei, 2000
 **************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#include <dos.h>
#include <limits.h>
#include <lkey.h>
#include <lsys.h>

#define TRUE  1
#define FALSE 0
#define MIDI_LAYERS   4
#define MIDI_TRACKS  32
////////////////////////////////////////////////////////////////////////////
char   *lmMidiMapFile[2]={ "","" };
#define TIMERS_PER_SECOND     1193181L
#define SECS_TO_TIMER(x)      ((long)(x) * TIMERS_PER_SECOND)
#define MSEC_TO_TIMER(x)      ((long)(x) * (TIMERS_PER_SECOND / 1000))
#define BPS_TO_TIMER(x)       (TIMERS_PER_SECOND / (long)(x))
#define BPM_TO_TIMER(x)       ((60 * TIMERS_PER_SECOND) / (long)(x))

typedef struct MIDI_DRIVER             /* driver for playing midi music */
{
   char *name;                         /* driver name */
   char *desc;                         /* description string */
   int  voices;                        /* available voices */
   int  basevoice;                     /* voice number offset */
   int  max_voices;                    /* maximum voices we can support */
   int  def_voices;                    /* default number of voices to use */
   int  xmin, xmax;                    /* reserved voice range */

   /* setup routines */
   int  (*detect)();
   int  (*init)(int voices);
   void (*exit)();
   int  (*mixer_volume)(int volume);

   /* raw MIDI output to MPU-401, etc. */
   void (*raw_midi)(unsigned char data);

   /* dynamic patch loading routines */
   int  (*load_patches)(char *patches, char *drums);
   void (*adjust_patches)(char *patches, char *drums);

   /* note control functions */
   void (*key_on)(int inst, int note, int bend, int vol, int pan);
   void (*key_off)(int voice);
   void (*set_volume)(int voice, int vol);
   void (*set_pitch)(int voice, int note, int bend);
   void (*set_pan)(int voice, int pan);
   void (*set_vibrato)(int voice, int amount);
} MIDI_DRIVER;
extern volatile long _midi_tick;
extern MIDI_DRIVER *midi_driver;
#define MIDI_NONE    0
#define MIDI_OPL2    1
#define MIDI_OPL3    2
#define MIDI_2XOPL2  3
////////////////////////////////////////////////////////////////////////////
typedef struct MIDI_TRACK                       /* a track in the MIDI file */
{
   unsigned char *pos;                          /* position in track data */
   long timer;                                  /* time until next event */
   unsigned char running_status;                /* last MIDI event */
} MIDI_TRACK;
typedef struct MIDI_CHANNEL                     /* a MIDI channel */
{
   int patch;                                   /* current sound */
   int volume;                                  /* volume controller */
   int pan;                                     /* pan position */
   int pitch_bend;                              /* pitch bend position */
   int new_volume;                              /* cached volume change */
   int new_pitch_bend;                          /* cached pitch bend */
   int note[128][MIDI_LAYERS];                  /* status of each note */
} MIDI_CHANNEL;
typedef struct MIDI_VOICE                         /* a voice on the soundcard */
{
   int channel;                                 /* MIDI channel */
   int note;                                    /* note (-1 = off) */
   int volume;                                  /* note velocity */
   int time;                                   /* when note was triggered */
} MIDI_VOICE;
typedef struct WAITING_NOTE                     /* a stored note-on request */
{
   int channel;
   int note;
   int volume;
} WAITING_NOTE;
typedef struct PATCH_TABLE                      /* GM -> external synth */
{
   int bank1;                                   /* controller #0 */
   int bank2;                                   /* controller #32 */
   int prog;                                    /* program change */
   int pitch;                                   /* pitch shift */
} PATCH_TABLE;
volatile long midi_pos = -1;                    /* position in MIDI file */
static long midi_pos_counter;                   /* delta for midi_pos */
volatile long _midi_tick = 0;                   /* counter for killing notes */

static void midi_player();                      /* core MIDI player routine */
static void prepare_to_play(MIDI *midi);
static void midi_lock_mem();

static MIDI *midifile = NULL;                   /* the file that is playing */
static short midi_loop = 0;                     /* repeat at eof? */
long midi_loop_start = -1;                      /* where to loop back to */
long midi_loop_end = -1;                        /* loop at this position */
static int midi_semaphore = 0;                  /* reentrancy flag */
static int midi_loaded_patches = FALSE;         /* loaded entire patch set? */
static long  midi_timer_speed;                    /* midi_player's timer speed */
static int midi_pos_speed;                      /* MIDI delta -> midi_pos */
static int midi_speed;                          /* MIDI delta -> timer */
static int midi_new_speed;                      /* for tempo change events */
static int old_midi_volume = -1;                /* stored global volume */
short  lm_midi_volume=255;
static int midi_alloc_channel;                  /* so _midi_allocate_voice */
static int midi_alloc_note;                     /* knows which note the */
static int midi_alloc_vol;                      /* sound is associated with */

static MIDI_TRACK midi_track[MIDI_TRACKS];      /* the active tracks */
static MIDI_VOICE midi_voice[MIDI_VOICES];      /* synth voice status */
static MIDI_CHANNEL midi_channel[16];           /* MIDI channel info */
static WAITING_NOTE midi_waiting[MIDI_VOICES];  /* notes still to be played */
static PATCH_TABLE patch_table[128];            /* GM -> external synth */

static short midi_seeking;                        /* set during seeks */
static short midi_looping;                        /* set during loops */
void (*midi_msg_callback)(int msg, int byte1, int byte2) = NULL;
void (*midi_meta_callback)(int type, unsigned char *data, int length) = NULL;
void (*midi_sysex_callback)(unsigned char *data, int length) = NULL;
MIDI_DRIVER *midi_driver;
////////////////////////////////////////////////////////////////////////////
static char lmMidiFlag=0;
char  lm_error_msg[150];
char  lmMidiInit(char driver);
char  lmMidiRest();
void  lmFM_load_map(int choice,int drums);
int   lmFM_load_ibk(char *filename, int drums);
MIDI *lmLoadMidi(char *fname,long file_offset);
void  lmDestroyMidi(MIDI*);
int   lmMidiPlay(MIDI *midi, int loop);
void  lmStopMidi();
void  lmMidiPause();
int   lmMidiSeek(int target);
void  lmMidiResume();
////////////////////////////////////////////////////////////////////////////
static int  midi_init(char driver);
static void midi_exit();

char lmMidiInit(char driver)
{ if (lmMidiFlag) return 1;
  if (!lk_sb_port) { sprintf(lsys_message,"Sound card init failed\n"); return 0; }
  if (!midi_init(driver)) return FALSE;
  lmMidiFlag=1; return 1;
}
char lmMidiRest()
{ if (!lmMidiFlag) return 0;
  midi_exit(); 
  lmMidiFlag=0;
  return 1;
}
static int   mfgetw(FILE *f)
{ unsigned short w[2],i;
  for (i=0;i<2;i++) w[i]=fgetc(f); 
  return (unsigned)w[0]*256+w[1];
}
static long  mfgetl(FILE *f)
{ unsigned w[4],i; 
  for (i=0;i<4;i++) w[i]=fgetc(f); 
  return (w[0]*256+w[1])*65536L+w[2]*256+w[3];
}
void lmDestroyMidi(MIDI *);
void lmStopMidi() { lmMidiPlay(NULL, FALSE); }
MIDI *lmLoadMidi(char *filename,long file_offset)
{
   int c;
   char buf[256];
   long data,retsiz;
   FILE *fp;
   MIDI *midi;
   int num_tracks;

   fp = fopen(filename, "rb");        /* open the file */
   if (!fp) return NULL; 

   midi = (MIDI*)malloc(sizeof(MIDI));              /* get some memory */
   if (!midi) {
      fclose(fp); return NULL;
   }

   for (c=0; c<MIDI_TRACKS; c++) {
      midi->track[c].data = NULL;
      midi->track[c].len = 0;
   }
  
   fseek(fp, file_offset, SEEK_SET);
   fread(buf, 4, 1, fp);                   /* read midi header */
   if (memcmp(buf, "MThd", 4)) goto err; 
   mfgetl(fp);                            /* skip header chunk length */

   data = mfgetw(fp);                    /* MIDI file type */
   if ((data != 0) && (data != 1)) goto err; 
   num_tracks = mfgetw(fp);              /* number of tracks */
   if ((num_tracks < 1) || (num_tracks > MIDI_TRACKS)) goto err; 

   data = mfgetw(fp);                    /* beat divisions */
   midi->divisions = abs(data);

   for (c=0; c<num_tracks; c++) {            /* read each track */
      fread(buf, 4, 1, fp);                  /* read track header */
      if (memcmp(buf, "MTrk", 4)) goto err; 
      data = mfgetl(fp);                      /* length of track chunk */
      midi->track[c].len = data;
      midi->track[c].data = (unsigned char*)malloc(data);    /* allocate memory */
      if (!midi->track[c].data) goto err; 
					     /* finally, read track data */
      retsiz=fread(midi->track[c].data, 1, data, fp);
      if ( retsiz != data) goto err; 
   }

   fclose(fp);
   return midi;

   /* oh dear... */
   err:
   fclose(fp);
   lmDestroyMidi(midi);
   return NULL;
}
void lmDestroyMidi(MIDI *midi)
{
   int c;

   if (midi == midifile)
      lmStopMidi();

   if (midi) {
      for (c=0; c<MIDI_TRACKS; c++) {
	 if (midi->track[c].data) {
	    free(midi->track[c].data);
	 }
      }
      free(midi);
   }
}
static unsigned long parse_var_len(unsigned char **data)
{
   unsigned long val = **data & 0x7F;

   while (**data & 0x80) {
      (*data)++;
      val <<= 7;
      val += (**data & 0x7F);
   }

   (*data)++;
   return val;
}
/* global_volume_fix:
 *  Converts a note volume, adjusting it according to the global 
 *  _midi_volume variable.
 */
static inline int global_volume_fix(int vol)
{
   if (lm_midi_volume >= 0)
      return (vol * lm_midi_volume) / 256;

   return vol;
}
/* sort_out_volume:
 *  Converts a note volume, adjusting it according to the channel volume
 *  and the global _midi_volume variable.
 */
static inline int sort_out_volume(int c, int vol)
{
   return global_volume_fix((vol * midi_channel[c].volume) / 128);
}
/* raw_program_change:
 *  Sends a program change message to a device capable of handling raw
 *  MIDI data, using patch mapping tables. Assumes that midi_driver->raw_midi
 *  isn't NULL, so check before calling it!
 */
static void raw_program_change(int channel, int patch)
{
   if (channel != 9) {
      /* bank change #1 */
      if (patch_table[patch].bank1 >= 0) {
	 midi_driver->raw_midi(0xB0+channel);
	 midi_driver->raw_midi(0);
	 midi_driver->raw_midi(patch_table[patch].bank1);
      }

      /* bank change #2 */
      if (patch_table[patch].bank2 >= 0) {
	 midi_driver->raw_midi(0xB0+channel);
	 midi_driver->raw_midi(32);
	 midi_driver->raw_midi(patch_table[patch].bank2);
      }

      /* program change */
      midi_driver->raw_midi(0xC0+channel);
      midi_driver->raw_midi(patch_table[patch].prog);

      /* update volume */
      midi_driver->raw_midi(0xB0+channel);
      midi_driver->raw_midi(7);
      midi_driver->raw_midi(global_volume_fix(midi_channel[channel].volume-1));
   }
}
/* midi_note_off:
 *  Processes a MIDI note-off event.
 */
static void midi_note_off(int channel, int note)
{
   int done = FALSE;
   int voice, layer;
   int c;

   /* can we send raw MIDI data? */
   if (midi_driver->raw_midi) {
      if (channel != 9)
	 note += patch_table[midi_channel[channel].patch].pitch;

      midi_driver->raw_midi(0x80+channel);
      midi_driver->raw_midi(note);
      midi_driver->raw_midi(0);
      return;
   }

   /* oh well, have to do it the long way... */
   for (layer=0; layer<MIDI_LAYERS; layer++) {
      voice = midi_channel[channel].note[note][layer];
      if (voice >= 0) {
	 midi_driver->key_off(voice + midi_driver->basevoice);
	 midi_voice[voice].note = -1;
	 midi_voice[voice].time = _midi_tick;
	 midi_channel[channel].note[note][layer] = -1; 
	 done = TRUE;
      }
   }

   /* if the note isn't playing, it must still be in the waiting room */
   if (!done) {
      for (c=0; c<MIDI_VOICES; c++) {
	 if ((midi_waiting[c].channel == channel) && 
	     (midi_waiting[c].note == note)) {
	    midi_waiting[c].note = -1;
	    break;
	 }
      }
   }
}
/* sort_out_pitch_bend:
 *  MIDI pitch bend range is + or - two semitones. The low-level soundcard
 *  drivers can only handle bends up to +1 semitone. This routine converts
 *  pitch bends from MIDI format to our own format.
 */
static inline void sort_out_pitch_bend(int *bend, int *note)
{
   if (*bend == 0x2000) {
      *bend = 0;
      return;
   }

   (*bend) -= 0x2000;

   while (*bend < 0) {
      (*note)--;
      (*bend) += 0x1000;
   }

   while (*bend >= 0x1000) {
      (*note)++;
      (*bend) -= 0x1000;
   }
}



/* _midi_allocate_voice:
 *  Allocates a MIDI voice in the range min-max (inclusive). This is 
 *  intended to be called by the key_on() handlers in the MIDI driver, 
 *  and shouldn't be used by any other code.
 */
int lm_midi_allocate_voice(int min, int max)
{
   int c;
   int layer;
   int voice = -1;
   int best_time = LONG_MAX;

   if (min < 0)
      min = 0;

   if (max < 0)
      max = midi_driver->voices-1;

   /* which layer can we use? */
   for (layer=0; layer<MIDI_LAYERS; layer++)
      if (midi_channel[midi_alloc_channel].note[midi_alloc_note][layer] < 0)
	 break; 

   if (layer >= MIDI_LAYERS)
      return -1;

   /* find a free voice */
   for (c=min; c<=max; c++) {
      if ((midi_voice[c].note < 0) && 
	  (midi_voice[c].time < best_time) && 
	  ((c < midi_driver->xmin) || (c > midi_driver->xmax))) {
	 voice = c;
	 best_time = midi_voice[c].time;
      }
   }

   /* if there are no free voices, kill a note to make room */
   if (voice < 0) {
      voice = -1;
      best_time = LONG_MAX;
      for (c=min; c<=max; c++) {
	 if ((midi_voice[c].time < best_time) && 
	     ((c < midi_driver->xmin) || (c > midi_driver->xmax))) {
	    voice = c;
	    best_time = midi_voice[c].time;
	 }
      }
      if (voice >= 0)
	 midi_note_off(midi_voice[voice].channel, midi_voice[voice].note);
      else
	 return -1;
   }

   /* ok, we got it... */
   midi_voice[voice].channel = midi_alloc_channel;
   midi_voice[voice].note = midi_alloc_note;
   midi_voice[voice].volume = midi_alloc_vol;
   midi_voice[voice].time = _midi_tick;
   midi_channel[midi_alloc_channel].note[midi_alloc_note][layer] = voice; 

   return voice + midi_driver->basevoice;
}
/* midi_note_on:
 *  Processes a MIDI note-on event. Tries to find a free soundcard voice,
 *  and if it can't either cuts off an existing note, or if 'polite' is
 *  set, just stores the channel, note and volume in the waiting list.
 */
static void midi_note_on(int channel, int note, int vol, int polite)
{
   int c, layer, inst, bend, corrected_note;

   /* it's easy if the driver can handle raw MIDI data */
   if (midi_driver->raw_midi) {
      if (channel != 9)
	 note += patch_table[midi_channel[channel].patch].pitch;

      midi_driver->raw_midi(0x90+channel);
      midi_driver->raw_midi(note);
      midi_driver->raw_midi(vol);
      return;
   }

   /* if the note is already on, turn it off */
   for (layer=0; layer<MIDI_LAYERS; layer++) {
      if (midi_channel[channel].note[note][layer] >= 0) {
	 midi_note_off(channel, note);
	 return;
      }
   }

   /* if zero volume and the note isn't playing, we can just ignore it */
   if (vol == 0)
      return;

   if (channel != 9) {
      /* are there any free voices? */
      for (c=0; c<midi_driver->voices; c++)
	 if ((midi_voice[c].note < 0) && 
	     ((c < midi_driver->xmin) || (c > midi_driver->xmax)))
	    break;

      /* if there are no free voices, remember the note for later */
      if ((c >= midi_driver->voices) && (polite)) {
	 for (c=0; c<MIDI_VOICES; c++) {
	    if (midi_waiting[c].note < 0) {
	       midi_waiting[c].channel = channel;
	       midi_waiting[c].note = note;
	       midi_waiting[c].volume = vol;
	       break;
	    }
	 }
	 return;
      }
   }

   /* drum sound? */
   if (channel == 9) {
      inst = 128+note;
      corrected_note = 60;
      bend = 0;
   }

?? 快捷鍵說明

復(fù)制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號(hào) Ctrl + =
減小字號(hào) Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
欧美中文字幕一区二区三区| 色一区在线观看| 欧美色国产精品| 久久久久久久久久久99999| 依依成人精品视频| 久久99国产精品久久| 色婷婷av一区二区三区大白胸| 成人黄色电影在线| 日韩欧美视频在线| 一区二区三区四区视频精品免费 | 亚洲成年人网站在线观看| 国产精品白丝jk白祙喷水网站| 欧美日韩国产成人在线91| 亚洲欧洲日韩女同| 激情亚洲综合在线| 欧美男人的天堂一二区| 亚洲色图欧美偷拍| 丰满放荡岳乱妇91ww| 日韩视频国产视频| 午夜日韩在线观看| 91啪亚洲精品| 国产精品嫩草影院av蜜臀| 国产酒店精品激情| 日韩限制级电影在线观看| 亚洲国产视频网站| 色视频成人在线观看免| 国产精品久久久久久久久免费樱桃| 久久精品99久久久| 欧美一二三区在线观看| 亚洲成a人片在线观看中文| 色综合久久久久| 国产精品久久久久影院亚瑟| 国产成人亚洲综合a∨婷婷| 精品日韩欧美在线| 蜜臀av性久久久久蜜臀av麻豆| 久久综合九色综合97婷婷女人| 久久久99久久精品欧美| 国产精品资源网| 国产成人综合视频| 日韩欧美一级特黄在线播放| 伊人一区二区三区| 欧美精品第1页| 日本成人在线不卡视频| 国产亚洲欧美一区在线观看| 成人毛片视频在线观看| 一区二区久久久久| 国产精品青草久久| 日本女人一区二区三区| 欧美日韩电影在线| 亚洲va欧美va人人爽午夜| 欧美三级韩国三级日本一级| 香蕉成人伊视频在线观看| 欧美日韩精品欧美日韩精品一| 一区二区久久久久| 91精品欧美综合在线观看最新| 性做久久久久久免费观看欧美| 在线观看91av| 另类小说综合欧美亚洲| 精品国产成人系列| 国产91在线看| 亚洲欧美另类图片小说| 在线观看av不卡| 秋霞影院一区二区| 久久伊人蜜桃av一区二区| 国产精品自产自拍| 中文字幕亚洲在| 在线一区二区视频| 丝袜美腿亚洲综合| 欧美videos中文字幕| 国产不卡视频在线播放| 亚洲免费在线电影| 51精品国自产在线| 狠狠色狠狠色综合系列| 中文字幕日韩av资源站| 在线看日本不卡| 美腿丝袜亚洲综合| 国产丝袜欧美中文另类| 91美女片黄在线观看91美女| 午夜不卡在线视频| 久久久一区二区三区| av在线不卡免费看| 亚洲午夜电影在线观看| 欧美mv日韩mv国产网站| 成人免费视频国产在线观看| 亚洲在线免费播放| 日韩女优毛片在线| 99在线精品观看| 五月开心婷婷久久| 国产日产欧美一区| 欧美无砖砖区免费| 国产美女在线观看一区| 亚洲免费高清视频在线| 欧美一区二区三区免费| 成人免费毛片a| 污片在线观看一区二区| 国产日韩成人精品| 欧美欧美午夜aⅴ在线观看| 国产91精品在线观看| 亚洲成av人片一区二区梦乃| 中文字幕免费一区| 欧美猛男gaygay网站| 成人午夜在线播放| 日本欧美韩国一区三区| 国产精品免费久久| 日韩欧美一级片| 在线视频一区二区免费| 国产精品影视网| 婷婷久久综合九色国产成人 | 国产91富婆露脸刺激对白| 亚洲午夜精品在线| 国产精品丝袜在线| 日韩免费成人网| 欧洲一区在线电影| 成人亚洲一区二区一| 美女www一区二区| 亚洲最大色网站| 日本一区二区三区电影| 91精品欧美一区二区三区综合在 | 欧美亚洲国产一区二区三区| 国产曰批免费观看久久久| 一区二区三区四区乱视频| 久久亚洲综合色| 欧美老年两性高潮| va亚洲va日韩不卡在线观看| 国产一区欧美一区| 欧美aaa在线| 亚洲国产精品影院| 亚洲欧美日韩国产手机在线| 国产亲近乱来精品视频| 日韩欧美高清dvd碟片| 欧美日韩一级黄| 色婷婷精品大在线视频| 不卡av在线网| 国产精品亚洲人在线观看| 免播放器亚洲一区| 亚洲香蕉伊在人在线观| 亚洲狼人国产精品| 国产精品系列在线| 久久久久久久久免费| 精品三级在线看| 日韩欧美亚洲国产另类 | 色综合久久综合网欧美综合网| 国产成人综合在线| 国产美女在线精品| 国产综合一区二区| 麻豆精品在线视频| 日本不卡123| 日韩电影网1区2区| 亚洲成人一区二区在线观看| 亚洲一区二区av在线| 亚洲最新视频在线播放| 一区二区成人在线| 亚洲精品视频自拍| 亚洲桃色在线一区| 亚洲人成精品久久久久久| 国产精品灌醉下药二区| 中文字幕欧美日韩一区| 国产精品人妖ts系列视频| 欧美激情在线一区二区| 欧美国产欧美综合| 国产精品久久久久久久久图文区| 国产精品久久福利| 亚洲欧洲精品天堂一级 | 久久久精品免费网站| 久久久久久久久99精品| 国产午夜亚洲精品午夜鲁丝片| 久久久午夜电影| 国产精品免费视频一区| 日韩一区在线看| 夜夜嗨av一区二区三区| 亚洲va天堂va国产va久| 日本人妖一区二区| 激情综合色丁香一区二区| 国产精品91一区二区| 成人免费视频一区二区| 色婷婷综合五月| 欧美日韩国产在线播放网站| 717成人午夜免费福利电影| 欧美一区二区播放| 精品第一国产综合精品aⅴ| 久久人人爽爽爽人久久久| 国产日韩精品一区| 亚洲女人****多毛耸耸8| 亚洲一区在线观看免费观看电影高清| 亚洲444eee在线观看| 青草国产精品久久久久久| 精品一区二区久久| 99久久国产综合精品色伊| 欧美在线观看视频一区二区| 欧美一区二区三区播放老司机| 精品国一区二区三区| 亚洲国产高清不卡| 亚洲香蕉伊在人在线观| 国内精品久久久久影院色| 不卡一区二区在线| 欧美日韩精品是欧美日韩精品| 欧美成人一区二区三区| 国产精品无圣光一区二区| 亚洲v中文字幕| 激情综合一区二区三区|