📄 mplayer.c
字号:
dat=UniGetByte(); if (!pf->vbtick) { if (dat) a->fportupspd=dat; if (a->period) a->tmpperiod-=(a->fportupspd<<2); } break; case UNI_XMEFFECTE2: /* XM fineslide dn */ dat=UniGetByte(); if (!pf->vbtick) { if (dat) a->fportdnspd=dat; if (a->period) a->tmpperiod+=(a->fportdnspd<<2); } break; case UNI_XMEFFECTEA: /* fine volume slide up */ dat=UniGetByte(); if (!pf->vbtick) if (dat) a->fslideupspd=dat; a->tmpvolume+=a->fslideupspd; if (a->tmpvolume>64) a->tmpvolume=64; break; case UNI_XMEFFECTEB: /* fine volume slide dn */ dat=UniGetByte(); if (!pf->vbtick) if (dat) a->fslidednspd=dat; a->tmpvolume-=a->fslidednspd; if (a->tmpvolume<0) a->tmpvolume=0; break; case UNI_XMEFFECTG: pf->volume=UniGetByte()<<1; if (pf->volume>128) pf->volume=128; break; case UNI_XMEFFECTH: DoXMGlobalSlide(UniGetByte()); break; case UNI_XMEFFECTL: dat=UniGetByte(); if ((!pf->vbtick)&&(a->i)) { UWORD points; INSTRUMENT *i=a->i; MP_VOICE *aout; if ((aout=a->slave)) { points=i->volenv[i->volpts-1].pos; aout->venv.p=aout->venv.env[(dat>points)?points:dat].pos; points=i->panenv[i->panpts-1].pos; aout->penv.p=aout->penv.env[(dat>points)?points:dat].pos; } } break; case UNI_XMEFFECTP: dat=UniGetByte(); if (pf->panflag) DoXMPanSlide(dat); break; case UNI_XMEFFECTX1: dat=UniGetByte(); if (dat) a->ffportupspd=dat; else dat=a->ffportupspd; if (a->period) { DoXMExtraFineSlideUp(dat); a->ownper=1; } break; case UNI_XMEFFECTX2: dat=UniGetByte(); if (dat) a->ffportdnspd=dat; else dat=a->ffportdnspd; if (a->period) { DoXMExtraFineSlideDown(dat); a->ownper=1; } break; case UNI_ITEFFECTG: dat=UniGetByte(); if (dat) { a->portspeed=dat; } if (a->period) { if ((!pf->vbtick)&&(a->newsamp)){ a->kick=KICK_NOTE; a->start=-1; } else a->kick=(a->kick==KICK_NOTE)?KICK_ENV:KICK_ABSENT; DoITToneSlide(); a->ownper=1; } break; case UNI_ITEFFECTH: /* IT vibrato */ dat=UniGetByte(); if (!pf->vbtick) { if (dat&0x0f) a->vibdepth=dat&0xf; if (dat&0xf0) a->vibspd=(dat&0xf0)>>2; } if (a->period) { DoITVibrato(); a->ownper=1; } break; case UNI_ITEFFECTI: /* IT tremor */ DoITTremor(UniGetByte()); a->ownvol=1; break; case UNI_ITEFFECTM: a->chanvol=UniGetByte(); if (a->chanvol>64) a->chanvol=64; else if (a->chanvol<0) a->chanvol=0; break; case UNI_ITEFFECTN: /* slide / fineslide channel volume */ DoITChanVolSlide(UniGetByte()); break; case UNI_ITEFFECTP: /* slide / fineslide channel panning */ dat=UniGetByte(); if (pf->panflag) DoITPanSlide(dat); break; case UNI_ITEFFECTT: /* slide / fineslide tempo */ DoITTempo(UniGetByte()); break; case UNI_ITEFFECTU: /* fine vibrato */ dat=UniGetByte(); if (!pf->vbtick) { if (dat&0x0f) a->vibdepth=dat&0xf; if (dat&0xf0) a->vibspd=(dat&0xf0)>>2; } if (a->period) { DoITFineVibrato(); a->ownper=1; } break; case UNI_ITEFFECTW: /* slide / fineslide global volume */ DoITGlobalSlide(UniGetByte()); break; case UNI_ITEFFECTY: /* panbrello */ dat=UniGetByte(); if (!pf->vbtick) { if (dat&0x0f) a->panbdepth=(dat&0xf); if (dat&0xf0) a->panbspd=(dat&0xf0)>>4; } if (pf->panflag) DoITPanbrello(); break; case UNI_ITEFFECTS0: DoSSEffects(UniGetByte()); break; case UNI_ITEFFECTZ: /* FIXME not yet implemented */ UniSkipOpcode(UNI_ITEFFECTZ); break; case UNI_ULTEFFECT9: DoULTSampleOffset(); break; case UNI_MEDSPEED: DoMEDSpeed(); break; case UNI_MEDEFFECTF1: DoEEffects(0x90|(pf->sngspd/2)); break; case UNI_MEDEFFECTF2: DoEEffects(0xd0|(pf->sngspd/2)); break; case UNI_MEDEFFECTF3: DoEEffects(0x90|(pf->sngspd/3)); break; case UNI_XMEFFECTZ: Player_SetSynchroValue(UniGetByte()); break; default: a->sliding=oldsliding; UniSkipOpcode(c); break; } }}static void DoNNAEffects(UBYTE dat){ int t; MP_VOICE *aout; dat&=0xf; aout=(a->slave)?a->slave:NULL; switch (dat) { case 0x0: /* past note cut */ for (t=0;t<md_sngchn;t++) if (pf->voice[t].master==a) pf->voice[t].fadevol=0; break; case 0x1: /* past note off */ for (t=0;t<md_sngchn;t++) if (pf->voice[t].master==a) { pf->voice[t].keyoff|=KEY_OFF; if ((!(pf->voice[t].venv.flg & EF_ON))|| (pf->voice[t].venv.flg & EF_LOOP)) pf->voice[t].keyoff=KEY_KILL; } break; case 0x2: /* past note fade */ for (t=0;t<md_sngchn;t++) if (pf->voice[t].master==a) pf->voice[t].keyoff|=KEY_FADE; break; case 0x3: /* set NNA note cut */ a->nna=(a->nna&~NNA_MASK)|NNA_CUT; break; case 0x4: /* set NNA note continue */ a->nna=(a->nna&~NNA_MASK)|NNA_CONTINUE; break; case 0x5: /* set NNA note off */ a->nna=(a->nna&~NNA_MASK)|NNA_OFF; break; case 0x6: /* set NNA note fade */ a->nna=(a->nna&~NNA_MASK)|NNA_FADE; break; case 0x7: /* disable volume envelope */ if (aout) aout->volflg&=~EF_ON; break; case 0x8: /* enable volume envelope */ if (aout) aout->volflg|=EF_ON; break; case 0x9: /* disable panning envelope */ if (aout) aout->panflg&=~EF_ON; break; case 0xa: /* enable panning envelope */ if (aout) aout->panflg|=EF_ON; break; case 0xb: /* disable pitch envelope */ if (aout) aout->pitflg&=~EF_ON; break; case 0xc: /* enable pitch envelope */ if (aout) aout->pitflg|=EF_ON; break; }}void pt_UpdateVoices(int max_volume){ SWORD envpan,envvol,envpit; UWORD playperiod; SLONG vibval,vibdpt; ULONG tmpvol; MP_VOICE *aout; INSTRUMENT *i; SAMPLE *s; pf->totalchn=pf->realchn=0; for (mp_channel=0;mp_channel<md_sngchn;mp_channel++) { aout=&pf->voice[mp_channel]; i=aout->i; s=aout->s; if ((!s)||(!s->length)) continue; if (aout->period<40) aout->period=40; else if (aout->period>50000) aout->period=50000; if ((aout->kick==KICK_NOTE)||(aout->kick==KICK_KEYOFF)) { Voice_Play_internal(mp_channel,s,(aout->start==-1)?((s->flags&SF_UST_LOOP)?s->loopstart:0):aout->start); aout->fadevol=32768; aout->aswppos=0; } if (i && ((aout->kick==KICK_NOTE)||(aout->kick==KICK_ENV))) { StartEnvelope(&aout->venv,aout->volflg,i->volpts,i->volsusbeg, i->volsusend,i->volbeg,i->volend,i->volenv,aout->keyoff); StartEnvelope(&aout->penv,aout->panflg,i->panpts,i->pansusbeg, 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*=pf->volume; /* * max 128 */ tmpvol/=4194304UL; tmpvol*=pf->initvolume; /* * max 128 */ tmpvol/=128; /* fade out */ if (pf->sngpos>=pf->numpos) tmpvol=0; else tmpvol=(tmpvol*max_volume)/128; if ((aout->masterchn!=-1)&& pf->control[aout->masterchn].muted) Voice_SetVolume_internal(mp_channel,0); else { Voice_SetVolume_internal(mp_channel,tmpvol); if ((tmpvol)&&(aout->master)&&(aout->master->slave==aout)) pf->realchn++; pf->totalchn++; } if (aout->panning==PAN_SURROUND) Voice_SetPanning_internal(mp_channel,PAN_SURROUND); else if ((pf->panflag)&&(aout->penv.flg & EF_ON)) Voice_SetPanning_internal(mp_channel,DoPan(envpan,aout->panning)); else Voice_SetPanning_internal(mp_channel,aout->panning); if (aout->period && s->vibdepth) switch (s->vibtype) { case 0: vibval=avibtab[s->avibpos&127]; if (s->avibpos & 0x80) vibval=-vibval; break; case 1: vibval=64; if (s->avibpos & 0x80) vibval=-vibval; break; case 2: vibval=63-(((s->avibpos+128)&255)>>1); break; default: vibval=(((s->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 */ s->avibpos=(s->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) */ Voice_Stop_internal(mp_channel); pf->totalchn--; if ((tmpvol)&&(aout->master)&&(aout->master->slave==aout)) pf->realchn--; } else { Voice_SetFrequency_internal(mp_channel, getfrequency(pf->flags,playperiod)); /* 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; } } md_bpm=pf->bpm+pf->relspd; if (md_bpm<32) md_bpm=32; else if (md_bpm>255) md_bpm=255; }}/* Handles new notes or instruments */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=&pf->control[mp_channel]; if (pf->sngpos>=pf->numpos) { tr=pf->numtrk; pf->numrow=0; } else { tr=pf->patterns[(pf->positions[pf->sngpos]*pf->numchn)+mp_channel]; pf->numrow=pf->pattrows[pf->positions[pf->sngpos]]; } a->row=(tr<pf->numtrk)?UniFindRow(pf->tracks[tr],pf->patpos):NULL; a->newsamp=0; if (!pf->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->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->handle=s->handle; a->speed=s->speed; if (i) { if ((pf->panflag)&&(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=0; } 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 ((pf->panflag)&&(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; } } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -