⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mod.c

📁 MIDI解码程序(用VC编写)
💻 C
📖 第 1 页 / 共 5 页
字号:
	       i->pansusend, i->panbeg, i->panend, i->panenv, aout->keyoff);	  StartEnvelope (&aout->cenv, aout->pitflg, i->pitpts, i->pitsusbeg,	       i->pitsusend, i->pitbeg, i->pitend, i->pitenv, aout->keyoff);	  if (aout->cenv.flg & EF_ON)	    aout->masterperiod = GetPeriod ((UWORD) aout->note << 1, aout->master->speed);	}      aout->kick = KICK_ABSENT;      envvol = (!(aout->volflg & EF_ON)) ? 256 :	ProcessEnvelope (&aout->venv, 256, aout->keyoff);      envpan = (!(aout->panflg & EF_ON)) ? PAN_CENTER :	ProcessEnvelope (&aout->penv, PAN_CENTER, aout->keyoff);      envpit = (!(aout->pitflg & EF_ON)) ? 32 :	ProcessEnvelope (&aout->cenv, 32, aout->keyoff);      tmpvol = aout->fadevol;	/* max 32768 */      tmpvol *= aout->chanvol;	/* * max 64 */      tmpvol *= aout->volume;	/* * max 256 */      tmpvol /= 16384L;		/* tmpvol is max 32768 */      aout->totalvol = tmpvol >> 2;	/* totalvolume used to determine samplevolume */      tmpvol *= envvol;		/* * max 256 */      tmpvol *= mp.volume;	/* * max 128 */      tmpvol /= 4194304UL;      Voice_SetVolume (mp.channel, tmpvol);      if ((tmpvol) && (aout->master) && (aout->master->slave == aout))	mp.realchn++;      mp.totalchn++;      if (aout->panning == PAN_SURROUND)	Voice_SetPanning (mp.channel, PAN_SURROUND);      else if (aout->penv.flg & EF_ON)	Voice_SetPanning (mp.channel, DoPan (envpan, aout->panning));      else	Voice_SetPanning (mp.channel, aout->panning);      if (aout->period && s->vibdepth)	switch (s->vibtype)	  {	  case 0:	    vibval = avibtab[aout->avibpos & 127];	    if (aout->avibpos & 0x80)	      vibval = -vibval;	    break;	  case 1:	    vibval = 64;	    if (aout->avibpos & 0x80)	      vibval = -vibval;	    break;	  case 2:	    vibval = 63 - (((aout->avibpos + 128) & 255) >> 1);	    break;	  default:	    vibval = (((aout->avibpos + 128) & 255) >> 1) - 64;	    break;	  }      else	vibval = 0;      if (s->vibflags & AV_IT)	{	  if ((aout->aswppos >> 8) < s->vibdepth)	    {	      aout->aswppos += s->vibsweep;	      vibdpt = aout->aswppos;	    }	  else	    vibdpt = s->vibdepth << 8;	  vibval = (vibval * vibdpt) >> 16;	  if (aout->mflag)	    {	      if (!(pf->flags & UF_LINEAR))		vibval >>= 1;	      aout->period -= vibval;	    }	}      else	{	  /* do XM style auto-vibrato */	  if (!(aout->keyoff & KEY_OFF))	    {	      if (aout->aswppos < s->vibsweep)		{		  vibdpt = (aout->aswppos * s->vibdepth) / s->vibsweep;		  aout->aswppos++;		}	      else		vibdpt = s->vibdepth;	    }	  else	    {	      /* keyoff -> depth becomes 0 if final depth wasn't reached or	         stays at final level if depth WAS reached */	      if (aout->aswppos >= s->vibsweep)		vibdpt = s->vibdepth;	      else		vibdpt = 0;	    }	  vibval = (vibval * vibdpt) >> 8;	  aout->period -= vibval;	}      /* update vibrato position */      aout->avibpos = (aout->avibpos + s->vibrate) & 0xff;      /* process pitch envelope */      playperiod = aout->period;      if ((aout->pitflg & EF_ON) && (envpit != 32))	{	  long p1;	  envpit -= 32;	  if ((aout->note << 1) + envpit <= 0)	    envpit = -(aout->note << 1);	  p1 = GetPeriod (((UWORD) aout->note << 1) + envpit, aout->master->speed) - aout->masterperiod;	  if (p1 > 0)	    {	      if ((UWORD) (playperiod + p1) <= playperiod)		{		  p1 = 0;		  aout->keyoff |= KEY_OFF;		}	    }	  else if (p1 < 0)	    {	      if ((UWORD) (playperiod + p1) >= playperiod)		{		  p1 = 0;		  aout->keyoff |= KEY_OFF;		}	    }	  playperiod += p1;	}      if (!aout->fadevol)	{			/* check for a dead note (fadevol=0) */	  mp.totalchn--;	  if ((tmpvol) && (aout->master) && (aout->master->slave == aout))	    mp.realchn--;	}      else	{	  Voice_SetPeriod (mp.channel,		      getAmigaPeriod (pf->flags, playperiod));	  if (kick_voice)	    Voice_Play (mp.channel, s, (aout->start == -1) ? ((s->flags & SF_UST_LOOP) ? s->loopstart : 0) : aout->start);	  /* if keyfade, start substracting fadeoutspeed from fadevol: */	  if ((i) && (aout->keyoff & KEY_FADE))	    {	      if (aout->fadevol >= i->volfade)		aout->fadevol -= i->volfade;	      else		aout->fadevol = 0;	    }	}      if (mp.bpm != mp.newbpm || mp.sngspd != mp.oldsngspd) {	mp.bpm = mp.newbpm;	mp.oldsngspd = mp.sngspd;        Voice_NewTempo(mp.bpm, mp.sngspd);      }    }}/* Handles new notes or instruments */static void pt_Notes (void){  UBYTE c, inst;  int tr, funky;		/* funky is set to indicate note or instrument change */  for (mp.channel = 0; mp.channel < pf->numchn; mp.channel++)    {      a = &mp.control[mp.channel];      if (mp.sngpos >= pf->numpos)	{	  tr = pf->numtrk;	  mp.numrow = 0;	}      else	{	  tr = pf->patterns[(pf->positions[mp.sngpos] * pf->numchn) + mp.channel];	  mp.numrow = pf->pattrows[pf->positions[mp.sngpos]];	}      a->row = (tr < pf->numtrk) ? UniFindRow (pf->tracks[tr], mp.patpos) : NULL;      a->newsamp = 0;      if (!mp.vbtick)	a->notedelay = 0;      if (!a->row)	continue;      UniSetRow (a->row);      funky = 0;      while ((c = UniGetByte ()))	switch (c)	  {	  case UNI_NOTE:	    funky |= 1;	    a->oldnote = a->anote, a->anote = UniGetByte ();	    a->kick = KICK_NOTE;	    a->start = -1;	    a->sliding = 0;	    /* retrig tremolo and vibrato waves ? */	    if (!(a->wavecontrol & 0x80))	      a->trmpos = 0;	    if (!(a->wavecontrol & 0x08))	      a->vibpos = 0;	    if (!a->panbwave)	      a->panbpos = 0;	    break;	  case UNI_INSTRUMENT:	    inst = UniGetByte ();	    if (inst >= pf->numins)	      break;		/* safety valve */	    funky |= 2;	    a->i = (pf->flags & UF_INST) ? &pf->instruments[inst] : NULL;	    a->retrig = 0;	    a->s3mtremor = 0;	    a->ultoffset = 0;	    a->sample = inst;	    break;	  default:	    UniSkipOpcode (c);	    break;	  }      if (funky)	{	  INSTRUMENT *i;	  SAMPLE *s;	  i = a->i;	  if (i)	    {	      if (i->samplenumber[a->anote] >= pf->numsmp)		continue;	      s = &pf->samples[i->samplenumber[a->anote]];	      a->note = i->samplenote[a->anote];	    }	  else	    {	      a->note = a->anote;	      s = &pf->samples[a->sample];	    }	  if (a->s != s)	    {	      a->s = s;	      a->newsamp = a->period;	    }	  /* channel or instrument determined panning ? */	  a->panning = pf->panning[mp.channel];	  if (s->flags & SF_OWNPAN)	    a->panning = s->panning;	  else if ((i) && (i->flags & IF_OWNPAN))	    a->panning = i->panning;	  a->data = s->data;	  a->speed = s->speed;	  if (i)	    {	      if ((i->flags & IF_PITCHPAN)		  && (a->panning != PAN_SURROUND))		{		  a->panning += ((a->anote - i->pitpancenter) * i->pitpansep) / 8;		  if (a->panning < PAN_LEFT)		    a->panning = PAN_LEFT;		  else if (a->panning > PAN_RIGHT)		    a->panning = PAN_RIGHT;		}	      a->pitflg = i->pitflg;	      a->volflg = i->volflg;	      a->panflg = i->panflg;	      a->nna = i->nnatype;	      a->dca = i->dca;	      a->dct = i->dct;	    }	  else	    {	      a->pitflg = 0;	      a->volflg = 0;	      a->panflg = 0;	      a->nna = 0;	      a->dca = 0;	      a->dct = DCT_OFF;	    }	  if (funky & 2)	/* instrument change */	    {	      /* IT random volume variations: 0:8 bit fixed, and one bit for	         sign. */	      a->volume = a->tmpvolume = s->volume;	      if ((s) && (i))		{		  if (i->rvolvar)		    {		      a->volume = a->tmpvolume = s->volume +			((s->volume * ((SLONG) i->rvolvar * (SLONG) getrandom (512)			  )) / 25600);		      if (a->volume < 0)			a->volume = a->tmpvolume = 0;		      else if (a->volume > 64)			a->volume = a->tmpvolume = 64;		    }		  if ((a->panning != PAN_SURROUND))		    {		      a->panning += ((a->panning * ((SLONG) i->rpanvar *					 (SLONG) getrandom (512))) / 25600);		      if (a->panning < PAN_LEFT)			a->panning = PAN_LEFT;		      else if (a->panning > PAN_RIGHT)			a->panning = PAN_RIGHT;		    }		}	    }	  a->wantedperiod = a->tmpperiod = GetPeriod ((UWORD) a->note << 1, a->speed);	  a->keyoff = KEY_KICK;	}    }}/* Handles effects */static void pt_EffectsPass1 (void){  MP_VOICE *aout;  for (mp.channel = 0; mp.channel < pf->numchn; mp.channel++)    {      a = &mp.control[mp.channel];      if ((aout = a->slave))	{	  a->fadevol = aout->fadevol;	  a->period = aout->period;	  if (a->kick == KICK_KEYOFF)	    a->keyoff = aout->keyoff;	}      if (!a->row)	continue;      UniSetRow (a->row);      a->ownper = a->ownvol = 0;      mp.explicitslides = 0;      pt_playeffects ();      /* continue volume slide if necessary for XM and IT */      if (pf->flags & UF_BGSLIDES)	{	  if (!mp.explicitslides && a->sliding)	    DoS3MVolSlide(0);	  else if (a->tmpvolume)	    a->sliding = mp.explicitslides;	}      if (!a->ownper)	a->period = a->tmpperiod;      if (!a->ownvol)	a->volume = a->tmpvolume;      if (a->s)	{	  if (a->i)	    a->outvolume = (a->volume * a->s->globvol * a->i->globvol) >> 10;	  else	    a->outvolume = (a->volume * a->s->globvol) >> 4;	  if (a->outvolume > 256)	    a->volume = 256;	  else if (a->outvolume < 0)	    a->outvolume = 0;	}    }}/* NNA management */static void pt_NNA (void){  for (mp.channel = 0; mp.channel < pf->numchn; mp.channel++)    {      a = &mp.control[mp.channel];      if (a->kick == KICK_NOTE)	{	  BOOL k = 0;	  if (a->slave)	    {	      MP_VOICE *aout;	      aout = a->slave;	      if (aout->nna & NNA_MASK)		{		  /* Make sure the old MP_VOICE channel knows it has no		     master now ! */		  a->slave = NULL;		  /* assume the channel is taken by NNA */		  aout->mflag = 0;		  switch (aout->nna)		    {		    case NNA_CONTINUE:		/* continue note, do nothing */		      break;		    case NNA_OFF:	/* note off */		      aout->keyoff |= KEY_OFF;		      if ((!(aout->volflg & EF_ON)) || (aout->volflg & EF_LOOP))			aout->keyoff = KEY_KILL;		      break;		    case NNA_FADE:		      aout->keyoff |= KEY_FADE;		      break;		    }		}	    }	  if (a->dct != DCT_OFF)	    {	      int t;	      for (t = 0; t < MOD_NUM_VOICES; t++)		if ((!Voice_Stopped (t)) &&		    (mp.voice[t].masterchn == mp.channel) &&		    (a->sample == mp.voice[t].sample))		  {		    k = 0;		    switch (a->dct)		      {		      case DCT_NOTE:			if (a->note == mp.voice[t].note)			  k = 1;			break;		      case DCT_SAMPLE:			if (a->data == mp.voice[t].data)			  k = 1;			break;		      case DCT_INST:			k = 1;			break;		      }		    if (k)		      switch (a->dca)			{			case DCA_CUT:			  mp.voice[t].fadevol = 0;			  break;			case DCA_OFF:			  mp.voice[t].keyoff |= KEY_OFF;			  if ((!(mp.voice[t].volflg & EF_ON)) ||			      (mp.voice[t].volflg & EF_LOOP))			    mp.voice[t].keyoff = KEY_KILL;			  break;			case DCA_FADE:			  mp.voice[t].keyoff |= KEY_FADE;			  break;			}		  }	    }	}			/* if (a->kick==KICK_NOTE) */    }}/* Setup module and NNA voices */static void pt_SetupVoices (void){  MP_VOICE *aout;  for (mp.channel = 0; mp.channel < pf->numchn; mp.channel++)    {      a = &mp.control[mp.channel];      if (a->notedelay)	continue;      if (a->kick == KICK_NOTE)	{	  /* if no channel was cut above, find an empty or quiet channel	     here */	  if (pf->flags & UF_NNA)	    {	      if (!a->slave)		{		  int newchn;		  if ((newchn = MP_FindEmptyChannel ()) != -1)		    a->slave = &mp.voice[a->slavechn = newchn];		}	    }	  else	    a->slave = &mp.voice[a->slavechn = mp.channel];	  /* assign parts of MP_VOICE only done for a KICK_NOTE */	  if ((aout = a->slave))	    {	      if (aout->mflag && aout->master)		aout->master->slave = NULL;	      aout->master = a;	      a->slave = aout;	      aout->masterchn = mp.channel;	      aout->mflag = 1;	    }	}      else	aout = a->slave;      if (aout)	{	  aout->i = a->i;	  aout->s = a->s;	  aout->sample = a->sample;	  aout->data = a->data;	  aout->period = a->period;	  aout->panning = a->panning;	  aout->chanvol = a->chanvol;	  aout->fadevol = a->fadevol;	  aout->kick = a->kick;	  aout->start = a->start;	  aout->volflg = a->volflg;	  aout->panflg = a->panflg;	  aout->pitflg = a->pitflg;	  aout->volume = a->outvolume;	  aout->keyoff = a->keyoff;	  aout->note = a->note;	  aout->nna = a->nna;	}      a->kick = KICK_ABSENT;    }}/* second effect pass */static void pt_EffectsPass2 (void){  UBYTE c;  for (mp.channel = 0; mp.channel < pf->numchn; mp.channel++)    {      a = &mp.control[mp.channel];      if (!a->row)	continue;      UniSetRow (a->row);      while ((c = UniGetByte ()))	if (c == UNI_ITEFFECTS0)	  {	    c = UniGetByte ();	    if ((c >> 4) == SS_S7EFFECTS)	      DoNNAEffects (c & 0xf);	  }	else	  UniSkipOpcode (c);    }}static BOOL HandleTick (void){  if ((!pf) || (mp.sngpos >= pf->numpos))    return 0;  if (++mp.vbtick >= mp.sngspd)    {      if (mp.pat_repcrazy)	mp.pat_repcrazy = 0;	/* play 2 times row 0 */      else	mp.patpos++;      mp.vbtick = 0;      /* process pattern-delay. mp.patdly2 is the counter and mp.patdly is         the command memory. */      if (mp.patdly)	mp.patdly2 = mp.patdly, mp.pat

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -