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

📄 load_imf.c

📁 MIDI解码程序(用VC编写)
💻 C
📖 第 1 页 / 共 2 页
字号:
/*      MikMod sound library   (c) 1998, 1999 Miodrag Vallat and others - see file AUTHORS for   complete list.   This library is free software; you can redistribute it and/or modify   it under the terms of the GNU Library General Public License as   published by the Free Software Foundation; either version 2 of   the License, or (at your option) any later version.   This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU Library General Public License for more details.   You should have received a copy of the GNU Library General Public   License along with this library; if not, write to the Free Software   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA   02111-1307, USA. *//*==============================================================================  $Id: load_imf.c,v 1.12 1999/10/25 16:31:41 miod Exp $  Imago Orpheus (IMF) module loader==============================================================================*/#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <string.h>#include "unimod_priv.h"/*========== Module structure *//* module header */typedef struct IMFHEADER  {    CHAR songname[32];    UWORD ordnum;    UWORD patnum;    UWORD insnum;    UWORD flags;    UBYTE initspeed;    UBYTE inittempo;    UBYTE mastervol;    UBYTE mastermult;    UBYTE orders[256];  }IMFHEADER;/* channel settings */typedef struct IMFCHANNEL  {    CHAR name[12];    UBYTE chorus;    UBYTE reverb;    UBYTE pan;    UBYTE status;  }IMFCHANNEL;/* instrument header */#define IMFNOTECNT (10*OCTAVE)#define IMFENVCNT (16*2)typedef struct IMFINSTHEADER  {    CHAR name[32];    UBYTE what[IMFNOTECNT];    UWORD volenv[IMFENVCNT];    UWORD panenv[IMFENVCNT];    UWORD pitenv[IMFENVCNT];    UBYTE volpts;    UBYTE volsus;    UBYTE volbeg;    UBYTE volend;    UBYTE volflg;    UBYTE panpts;    UBYTE pansus;    UBYTE panbeg;    UBYTE panend;    UBYTE panflg;    UBYTE pitpts;    UBYTE pitsus;    UBYTE pitbeg;    UBYTE pitend;    UBYTE pitflg;    UWORD volfade;    UWORD numsmp;    ULONG signature;  }IMFINSTHEADER;/* sample header */typedef struct IMFWAVHEADER  {    CHAR samplename[13];    ULONG length;    ULONG loopstart;    ULONG loopend;    ULONG samplerate;    UBYTE volume;    UBYTE pan;    UBYTE flags;  }IMFWAVHEADER;typedef struct IMFNOTE  {    UBYTE note, ins, eff1, dat1, eff2, dat2;  }IMFNOTE;/*========== Loader variables */static CHAR IMF_Version[] = "Imago Orpheus";static IMFNOTE *imfpat = NULL;static IMFHEADER *mh = NULL;/*========== Loader code */BOOL IMF_Test (void){  UBYTE id[4];  _mm_fseek (modreader, 0x3c, SEEK_SET);  if (!_mm_read_UBYTES (id, 4, modreader))    return 0;  if (!memcmp (id, "IM10", 4))    return 1;  return 0;}BOOL IMF_Init (void){  if (!(imfpat = (IMFNOTE *) _mm_malloc (32 * 256 * sizeof (IMFNOTE))))    return 0;  if (!(mh = (IMFHEADER *) _mm_malloc (sizeof (IMFHEADER))))    return 0;  return 1;}void IMF_Cleanup (void){  FreeLinear ();  _mm_free (imfpat);  _mm_free (mh);}static BOOL IMF_ReadPattern (SLONG size, UWORD rows){  int row = 0, flag, ch;  IMFNOTE *n, dummy;  /* clear pattern data */  memset (imfpat, 255, 32 * 256 * sizeof (IMFNOTE));  while ((size > 0) && (row < rows))    {      flag = _mm_read_UBYTE (modreader);      size--;      if (_mm_eof (modreader))	{	  _mm_errno = MMERR_LOADING_PATTERN;	  return 0;	}      if (flag)	{	  ch = remap[flag & 31];	  if (ch != -1)	    n = &imfpat[256 * ch + row];	  else	    n = &dummy;	  if (flag & 32)	    {	      n->note = _mm_read_UBYTE (modreader);	      if (n->note >= 0xa0)		n->note = 0xa0;	/* note off */	      n->ins = _mm_read_UBYTE (modreader);	      size -= 2;	    }	  if (flag & 64)	    {	      size -= 2;	      n->eff2 = _mm_read_UBYTE (modreader);	      n->dat2 = _mm_read_UBYTE (modreader);	    }	  if (flag & 128)	    {	      n->eff1 = _mm_read_UBYTE (modreader);	      n->dat1 = _mm_read_UBYTE (modreader);	      size -= 2;	    }	}      else	row++;    }  if ((size) || (row != rows))    {      _mm_errno = MMERR_LOADING_PATTERN;      return 0;    }  return 1;}static void IMF_ProcessCmd (UBYTE eff, UBYTE inf){  if ((eff) && (eff != 255))    switch (eff)      {      case 0x01:		/* set tempo */	UniEffect (UNI_S3MEFFECTA, inf);	break;      case 0x02:		/* set BPM */	if (inf >= 0x20)	  UniEffect (UNI_S3MEFFECTT, inf);	break;      case 0x03:		/* tone portamento */	UniEffect (UNI_ITEFFECTG, inf);	break;      case 0x04:		/* porta + volslide */	UniEffect (UNI_ITEFFECTG, inf);	UniEffect (UNI_S3MEFFECTD, 0);	break;      case 0x05:		/* vibrato */	UniPTEffect (0x4, inf);	break;      case 0x06:		/* vibrato + volslide */	UniPTEffect (0x4, inf);	UniEffect (UNI_S3MEFFECTD, 0);	break;      case 0x07:		/* fine vibrato */	UniEffect (UNI_ITEFFECTU, inf);	break;      case 0x08:		/* tremolo */	UniEffect (UNI_S3MEFFECTR, inf);	break;      case 0x09:		/* arpeggio */	UniPTEffect (0x0, inf);	break;      case 0x0a:		/* panning */	UniPTEffect (0x8, (inf >= 128) ? 255 : (inf << 1));	break;      case 0x0b:		/* pan slide */	UniEffect (UNI_XMEFFECTP, inf);	break;      case 0x0c:		/* set channel volume */	if (inf <= 64)	  UniPTEffect (0xc, inf);	break;      case 0x0d:		/* volume slide */	UniEffect (UNI_S3MEFFECTD, inf);	break;      case 0x0e:		/* fine volume slide */	if (inf)	  {	    if (inf >> 4)	      UniEffect (UNI_S3MEFFECTD, 0x0f | inf);	    else	      UniEffect (UNI_S3MEFFECTD, 0xf0 | inf);	  }	else	  UniEffect (UNI_S3MEFFECTD, 0);	break;      case 0x0f:		/* set finetune */	UniPTEffect (0xe, 0x50 | (inf >> 4));	break;#ifdef MIKMOD_DEBUG      case 0x10:		/* note slide up */      case 0x11:		/* not slide down */	fprintf (stderr, "\rIMF effect 0x10/0x11 (note slide)"		 " not implemented (eff=%2X inf=%2X)\n", eff, inf);	break;#endif      case 0x12:		/* slide up */	UniEffect (UNI_S3MEFFECTF, inf);	break;      case 0x13:		/* slide down */	UniEffect (UNI_S3MEFFECTE, inf);	break;      case 0x14:		/* fine slide up */	if (inf)	  {	    if (inf < 0x40)	      UniEffect (UNI_S3MEFFECTF, 0xe0 | (inf / 4));	    else	      UniEffect (UNI_S3MEFFECTF, 0xf0 | (inf >> 4));	  }	else	  UniEffect (UNI_S3MEFFECTF, 0);	break;      case 0x15:		/* fine slide down */	if (inf)	  {	    if (inf < 0x40)	      UniEffect (UNI_S3MEFFECTE, 0xe0 | (inf / 4));	    else	      UniEffect (UNI_S3MEFFECTE, 0xf0 | (inf >> 4));	  }	else	  UniEffect (UNI_S3MEFFECTE, 0);	break;	/* 0x16 set filter cutoff (awe32) */	/* 0x17 filter side + resonance (awe32) */      case 0x18:		/* sample offset */	UniPTEffect (0x9, inf);	break;#ifdef MIKMOD_DEBUG      case 0x19:		/* set fine sample offset */	fprintf (stderr, "\rIMF effect 0x19 (fine sample offset)"		 " not implemented (inf=%2X)\n", inf);	break;#endif      case 0x1a:		/* keyoff */	UniWriteByte (UNI_KEYOFF);	break;      case 0x1b:		/* retrig */	UniEffect (UNI_S3MEFFECTQ, inf);	break;      case 0x1c:		/* tremor */	UniEffect (UNI_S3MEFFECTI, inf);	break;      case 0x1d:		/* position jump */	UniPTEffect (0xb, inf);	break;      case 0x1e:		/* pattern break */	UniPTEffect (0xd, (inf >> 4) * 10 + (inf & 0xf));	break;      case 0x1f:		/* set master volume */	if (inf <= 64)	  UniEffect (UNI_XMEFFECTG, inf);	break;      case 0x20:		/* master volume slide */	UniEffect (UNI_XMEFFECTH, inf);	break;      case 0x21:		/* extended effects */	switch (inf >> 4)	  {	  case 0x1:		/* set filter */	  case 0x5:		/* vibrato waveform */	  case 0x8:		/* tremolo waveform */	    UniPTEffect (0xe, inf - 0x10);	    break;	  case 0xa:		/* pattern loop */	    UniPTEffect (0xe, 0x60 | (inf & 0xf));	    break;	  case 0xb:		/* pattern delay */	    UniPTEffect (0xe, 0xe0 | (inf & 0xf));	    break;	  case 0x3:		/* glissando */	  case 0xc:		/* note cut */	  case 0xd:		/* note delay */	  case 0xf:		/* invert loop */	    UniPTEffect (0xe, inf);	    break;	  case 0xe:		/* ignore envelope */	    UniEffect (UNI_ITEFFECTS0, 0x77);	/* vol */	    UniEffect (UNI_ITEFFECTS0, 0x79);	/* pan */	    UniEffect (UNI_ITEFFECTS0, 0x7b);	/* pit */	    break;	  }	break;	/* 0x22 chorus (awe32) */	/* 0x23 reverb (awe32) */      }}static UBYTE *IMF_ConvertTrack (IMFNOTE * tr, UWORD rows){  int t;  UBYTE note, ins;  UniReset ();  for (t = 0; t < rows; t++)    {      note = tr[t].note;      ins = tr[t].ins;      if ((ins) && (ins != 255))	UniInstrument (ins - 1);      if (note != 255)	{	  if (note == 0xa0)	    {

⌨️ 快捷键说明

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