load_xm.c

来自「linux上播放midi音乐,但是要一些设置.可网上查找. 软件名称: Ti」· C语言 代码 · 共 891 行 · 第 1/2 页

C
891
字号
      else	{	  for (v = 0; v < of.numchn; v++)	    of.tracks[numtrk++] = XM_Convert (NULL, ph.numrows);	}    }  if (dummypat)    {      of.pattrows[t] = 64;      if (!(xmpat = (XMNOTE *) _mm_calloc (64 * of.numchn, sizeof (XMNOTE))))	return 0;      for (v = 0; v < of.numchn; v++)	of.tracks[numtrk++] = XM_Convert (&xmpat[v * 64], 64);      free (xmpat);      xmpat = NULL;    }  return 1;}static BOOL LoadInstruments (void){  int t, u;  INSTRUMENT *d;  long next = 0;  UWORD wavcnt = 0;  if (!AllocInstruments ())    return 0;  d = of.instruments;  for (t = 0; t < of.numins; t++, d++)    {      XMINSTHEADER ih;      long headend;      memset (d->samplenumber, 0xff, INSTNOTES * sizeof (UWORD));      /* read instrument header */      headend = _mm_ftell (modreader);      ih.size = _mm_read_I_ULONG (modreader);      headend += ih.size;      _mm_read_string (ih.name, 22, modreader);      ih.type = _mm_read_UBYTE (modreader);      ih.numsmp = _mm_read_I_UWORD (modreader);      d->insname = DupStr (ih.name, 22, 1);      if ((SWORD) ih.size > 29)	{	  ih.ssize = _mm_read_I_ULONG (modreader);	  if (((SWORD) ih.numsmp > 0) && (ih.numsmp <= XMNOTECNT))	    {	      XMPATCHHEADER pth;	      int p;	      _mm_read_UBYTES (pth.what, XMNOTECNT, modreader);	      _mm_read_I_UWORDS (pth.volenv, XMENVCNT, modreader);	      _mm_read_I_UWORDS (pth.panenv, XMENVCNT, modreader);	      pth.volpts = _mm_read_UBYTE (modreader);	      pth.panpts = _mm_read_UBYTE (modreader);	      pth.volsus = _mm_read_UBYTE (modreader);	      pth.volbeg = _mm_read_UBYTE (modreader);	      pth.volend = _mm_read_UBYTE (modreader);	      pth.pansus = _mm_read_UBYTE (modreader);	      pth.panbeg = _mm_read_UBYTE (modreader);	      pth.panend = _mm_read_UBYTE (modreader);	      pth.volflg = _mm_read_UBYTE (modreader);	      pth.panflg = _mm_read_UBYTE (modreader);	      pth.vibflg = _mm_read_UBYTE (modreader);	      pth.vibsweep = _mm_read_UBYTE (modreader);	      pth.vibdepth = _mm_read_UBYTE (modreader);	      pth.vibrate = _mm_read_UBYTE (modreader);	      pth.volfade = _mm_read_I_UWORD (modreader);	      /* read the remainder of the header	         (2 bytes for 1.03, 22 for 1.04) */	      for (u = headend - _mm_ftell (modreader); u; u--)		_mm_read_UBYTE (modreader);	      /* #@!$&% fix for K_OSPACE.XM and possibly others */	      if(pth.volpts > XMENVCNT/2)	        pth.volpts = XMENVCNT/2;	      if(pth.panpts > XMENVCNT/2)	        pth.panpts = XMENVCNT/2;	      if ((_mm_eof (modreader)) || (pth.volpts > XMENVCNT / 2) || (pth.panpts > XMENVCNT / 2))		{		  if (nextwav)		    {		      free (nextwav);		      nextwav = NULL;		    }		  if (wh)		    {		      free (wh);		      wh = NULL;		    }		  _mm_errno = MMERR_LOADING_SAMPLEINFO;		  return 0;		}	      for (u = 0; u < XMNOTECNT; u++)		d->samplenumber[u] = pth.what[u] + of.numsmp;	      d->volfade = pth.volfade;#define XM_ProcessEnvelope(name) 											\ 				for (u = 0; u < (XMENVCNT / 2); u++) {						\ 					d->name##env[u].pos = pth.name##env[2*u];		\ 					d->name##env[u].val = pth.name##env[2*u + 1];	\ 				}															\				memcpy(d->name##env,pth.name##env,XMENVCNT);			\				if (pth.name##flg&1) d->name##flg|=EF_ON;				\				if (pth.name##flg&2) d->name##flg|=EF_SUSTAIN;			\				if (pth.name##flg&4) d->name##flg|=EF_LOOP;				\				d->name##susbeg=d->name##susend=pth.name##sus;		\				d->name##beg=pth.name##beg;								\				d->name##end=pth.name##end;								\				d->name##pts=pth.name##pts;								\																			\				/* scale envelope */										\				for (p=0;p<XMENVCNT/2;p++)									\					d->name##env[p].val<<=2;								\																			\				if ((d->name##flg&EF_ON)&&(d->name##pts<2))				\					d->name##flg&=~EF_ON;	      XM_ProcessEnvelope (vol);	      XM_ProcessEnvelope (pan);#undef XM_ProcessEnvelope	      /* Samples are stored outside the instrument struct now, so we	         have to load them all into a temp area, count the of.numsmp	         along the way and then do an AllocSamples() and move	         everything over */	      if (mh->version > 0x0103)		next = 0;	      for (u = 0; u < ih.numsmp; u++, s++)		{		  /* Allocate more room for sample information if necessary */		  if (of.numsmp + u == wavcnt)		    {		      wavcnt += XM_SMPINCR;		      if (!(nextwav = realloc (nextwav, wavcnt * sizeof (ULONG))))			{			  if (wh)			    {			      free (wh);			      wh = NULL;			    }			  _mm_errno = MMERR_OUT_OF_MEMORY;			  return 0;			}		      if (!(wh = realloc (wh, wavcnt * sizeof (XMWAVHEADER))))			{			  free (nextwav);			  nextwav = NULL;			  _mm_errno = MMERR_OUT_OF_MEMORY;			  return 0;			}		      s = wh + (wavcnt - XM_SMPINCR);		    }		  s->length = _mm_read_I_ULONG (modreader);		  s->loopstart = _mm_read_I_ULONG (modreader);		  s->looplength = _mm_read_I_ULONG (modreader);		  s->volume = _mm_read_UBYTE (modreader);		  s->finetune = _mm_read_SBYTE (modreader);		  s->type = _mm_read_UBYTE (modreader);		  s->panning = _mm_read_UBYTE (modreader);		  s->relnote = _mm_read_SBYTE (modreader);		  s->vibtype = pth.vibflg;		  s->vibsweep = pth.vibsweep;		  s->vibdepth = pth.vibdepth * 4;		  s->vibrate = pth.vibrate;		  s->reserved = _mm_read_UBYTE (modreader);		  _mm_read_string (s->samplename, 22, modreader);		  nextwav[of.numsmp + u] = next;		  next += s->length;		  if (_mm_eof (modreader))		    {		      free (nextwav);		      free (wh);		      nextwav = NULL;		      wh = NULL;		      _mm_errno = MMERR_LOADING_SAMPLEINFO;		      return 0;		    }		}	      if (mh->version > 0x0103)		{		  for (u = 0; u < ih.numsmp; u++)		    nextwav[of.numsmp++] += _mm_ftell (modreader);		  _mm_fseek (modreader, next, SEEK_CUR);		}	      else		of.numsmp += ih.numsmp;	    }	  else	    {	      /* read the remainder of the header */	      for (u = headend - _mm_ftell (modreader); u; u--)		_mm_read_UBYTE (modreader);	      if (_mm_eof (modreader))		{		  free (nextwav);		  free (wh);		  nextwav = NULL;		  wh = NULL;		  _mm_errno = MMERR_LOADING_SAMPLEINFO;		  return 0;		}	    }	}    }  /* sanity check */  if (!of.numsmp)    {      if (nextwav)	{	  free (nextwav);	  nextwav = NULL;	}      if (wh)	{	  free (wh);	  wh = NULL;	}      _mm_errno = MMERR_LOADING_SAMPLEINFO;      return 0;    }  return 1;}BOOL XM_Load (BOOL curious){  INSTRUMENT *d;  SAMPLE *q;  int t, u;  BOOL dummypat = 0;  char tracker[21], modtype[60];  /* try to read module header */  _mm_read_string (mh->id, 17, modreader);  _mm_read_string (mh->songname, 21, modreader);  _mm_read_string (mh->trackername, 20, modreader);  mh->version = _mm_read_I_UWORD (modreader);  if ((mh->version < 0x102) || (mh->version > 0x104))    {      _mm_errno = MMERR_NOT_A_MODULE;      return 0;    }  mh->headersize = _mm_read_I_ULONG (modreader);  mh->songlength = _mm_read_I_UWORD (modreader);  mh->restart = _mm_read_I_UWORD (modreader);  mh->numchn = _mm_read_I_UWORD (modreader);  mh->numpat = _mm_read_I_UWORD (modreader);  mh->numins = _mm_read_I_UWORD (modreader);  mh->flags = _mm_read_I_UWORD (modreader);  mh->tempo = _mm_read_I_UWORD (modreader);  mh->bpm = _mm_read_I_UWORD (modreader);  if (!mh->bpm)    {      _mm_errno = MMERR_NOT_A_MODULE;      return 0;    }  _mm_read_UBYTES (mh->orders, 256, modreader);  if (_mm_eof (modreader))    {      _mm_errno = MMERR_LOADING_HEADER;      return 0;    }  /* set module variables */  of.initspeed = mh->tempo;  of.inittempo = mh->bpm;  strncpy (tracker, mh->trackername, 20);  tracker[20] = 0;  for (t = 20; (tracker[t] <= ' ') && (t >= 0); t--)    tracker[t] = 0;  /* some modules have the tracker name empty */  if (!tracker[0])    strcpy (tracker, "Unknown tracker");#ifdef HAVE_SNPRINTF  snprintf (modtype, 60, "%s (XM format %d.%02d)",	    tracker, mh->version >> 8, mh->version & 0xff);#else  sprintf (modtype, "%s (XM format %d.%02d)",	   tracker, mh->version >> 8, mh->version & 0xff);#endif  of.modtype = safe_strdup (modtype);  of.numchn = mh->numchn;  of.numpat = mh->numpat;  of.numtrk = (UWORD) of.numpat * of.numchn;	/* get number of channels */  of.songname = DupStr (mh->songname, 20, 1);  of.numpos = mh->songlength;	/* copy the songlength */  of.reppos = mh->restart < mh->songlength ? mh->restart : 0;  of.numins = mh->numins;  of.flags |= UF_XMPERIODS | UF_INST | UF_BGSLIDES | UF_NOWRAP | UF_FT2QUIRKS;  if (mh->flags & 1)    of.flags |= UF_LINEAR;  memset (of.chanvol, 64, of.numchn);	/* store channel volumes */  if (!AllocPositions (of.numpos + 1))    return 0;  for (t = 0; t < of.numpos; t++)    of.positions[t] = mh->orders[t];  /* We have to check for any pattern numbers in the order list greater than     the number of patterns total. If one or more is found, we set it equal to     the pattern total and make a dummy pattern to workaround the problem */  for (t = 0; t < of.numpos; t++)    {      if (of.positions[t] >= of.numpat)	{	  of.positions[t] = of.numpat;	  dummypat = 1;	}    }  if (dummypat)    {      of.numpat++;      of.numtrk += of.numchn;    }  if (mh->version < 0x0104)    {      if (!LoadInstruments ())	return 0;      if (!LoadPatterns (dummypat))	return 0;      for (t = 0; t < of.numsmp; t++)	nextwav[t] += _mm_ftell (modreader);    }  else    {      if (!LoadPatterns (dummypat))	return 0;      if (!LoadInstruments ())	return 0;    }  if (!AllocSamples ())    {      free (nextwav);      free (wh);      nextwav = NULL;      wh = NULL;      return 0;    }  q = of.samples;  s = wh;  for (u = 0; u < of.numsmp; u++, q++, s++)    {      q->samplename = DupStr (s->samplename, 22, 1);      q->length = s->length;      q->loopstart = s->loopstart;      q->loopend = s->loopstart + s->looplength;      q->volume = s->volume;      q->speed = s->finetune + 128;      q->panning = s->panning;      q->seekpos = nextwav[u];      q->vibtype = s->vibtype;      q->vibsweep = s->vibsweep;      q->vibdepth = s->vibdepth;      q->vibrate = s->vibrate;      if (s->type & 0x10)	{	  q->length >>= 1;	  q->loopstart >>= 1;	  q->loopend >>= 1;	}      q->flags |= SF_OWNPAN;      if (s->type & 0x3)	q->flags |= SF_LOOP;      if (s->type & 0x2)	q->flags |= SF_BIDI;      if (s->type & 0x10)	q->flags |= SF_16BITS;      q->flags |= SF_DELTA | SF_SIGNED;    }  d = of.instruments;  s = wh;  for (u = 0; u < of.numins; u++, d++)    for (t = 0; t < XMNOTECNT; t++)      {	if (d->samplenumber[t] >= of.numsmp)	  d->samplenote[t] = 255;	else	  {	    int note = t + s[d->samplenumber[t]].relnote;	    d->samplenote[t] = (note < 0) ? 0 : note;	  }      }  free (wh);  free (nextwav);  wh = NULL;  nextwav = NULL;  return 1;}CHAR *XM_LoadTitle (void){  CHAR s[21];  _mm_fseek (modreader, 17, SEEK_SET);  if (!_mm_read_UBYTES (s, 21, modreader))    return NULL;  return (DupStr (s, 21, 1));}/*========== Loader information */MLOADER load_xm ={  NULL,  "XM",  "XM (FastTracker 2)",  XM_Init,  XM_Test,  XM_Load,  XM_Cleanup,  XM_LoadTitle};/* ex:set ts=4: */

⌨️ 快捷键说明

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