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

📄 load_med.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_med.c,v 1.27 1999/10/25 16:31:41 miod Exp $  Amiga MED module loader==============================================================================*/#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <string.h>#include "unimod_priv.h"/*========== Module information */typedef struct MEDHEADER  {    ULONG id;    ULONG modlen;    ULONG pMEDSONG;		/* struct MEDSONG *song; */    UWORD psecnum;		/* for the player routine, MMD2 only */    UWORD pseq;			/*  "   "   "   " */    ULONG pMEDBLOCKP;		/* struct MMD0Block **blockarr; */    ULONG reserved1;    ULONG ppMedInstrHdr;		/* struct InstrHdr **smplarr; */    ULONG reserved2;    ULONG pMEDEXP;		/* struct MEDEXP *expdata; */    ULONG reserved3;    UWORD pstate;		/* some data for the player routine */    UWORD pblock;    UWORD pline;    UWORD pseqnum;    SWORD actplayline;    UBYTE counter;    UBYTE extra_songs;		/* number of songs - 1 */  }MEDHEADER;typedef struct MEDSAMPLE  {    UWORD rep, replen;		/* offs: 0(s), 2(s) */    UBYTE midich;		/* offs: 4(s) */    UBYTE midipreset;		/* offs: 5(s) */    UBYTE svol;			/* offs: 6(s) */    SBYTE strans;		/* offs: 7(s) */  }MEDSAMPLE;typedef struct MEDSONG  {    MEDSAMPLE sample[63];	/* 63 * 8 bytes = 504 bytes */    UWORD numblocks;		/* offs: 504 */    UWORD songlen;		/* offs: 506 */    UBYTE playseq[256];		/* offs: 508 */    UWORD deftempo;		/* offs: 764 */    SBYTE playtransp;		/* offs: 766 */    UBYTE flags;		/* offs: 767 */    UBYTE flags2;		/* offs: 768 */    UBYTE tempo2;		/* offs: 769 */    UBYTE trkvol[16];		/* offs: 770 */    UBYTE mastervol;		/* offs: 786 */    UBYTE numsamples;		/* offs: 787 */  }MEDSONG;typedef struct MEDEXP  {    ULONG nextmod;		/* pointer to next module */    ULONG exp_smp;		/* pointer to InstrExt array */    UWORD s_ext_entries;    UWORD s_ext_entrsz;    ULONG annotxt;		/* pointer to annotation text */    ULONG annolen;    ULONG iinfo;		/* pointer to InstrInfo array */    UWORD i_ext_entries;    UWORD i_ext_entrsz;    ULONG jumpmask;    ULONG rgbtable;    ULONG channelsplit;    ULONG n_info;    ULONG songname;		/* pointer to songname */    ULONG songnamelen;    ULONG dumps;    ULONG reserved2[7];  }MEDEXP;typedef struct MMD0NOTE  {    UBYTE a, b, c;  }MMD0NOTE;typedef struct MMD1NOTE  {    UBYTE a, b, c, d;  }MMD1NOTE;typedef struct MEDINSTHEADER  {    ULONG length;    SWORD type;    /* Followed by actual data */  }MEDINSTHEADER;typedef struct MEDINSTEXT  {    UBYTE hold;    UBYTE decay;    UBYTE suppress_midi_off;    SBYTE finetune;  }MEDINSTEXT;typedef struct MEDINSTINFO  {    UBYTE name[40];  }MEDINSTINFO;/*========== Loader variables */#define MMD0_string 0x4D4D4430#define MMD1_string 0x4D4D4431static MEDHEADER *mh = NULL;static MEDSONG *ms = NULL;static MEDEXP *me = NULL;static ULONG *ba = NULL;static MMD0NOTE *mmd0pat = NULL;static MMD1NOTE *mmd1pat = NULL;static BOOL decimalvolumes;static BOOL bpmtempos;#define d0note(row,col) mmd0pat[((row)*(UWORD)of.numchn)+(col)]#define d1note(row,col) mmd1pat[((row)*(UWORD)of.numchn)+(col)]static CHAR MED_Version[] = "OctaMED (MMDx)";/*========== Loader code */BOOL MED_Test (void){  UBYTE id[4];  if (!_mm_read_UBYTES (id, 4, modreader))    return 0;  if ((!memcmp (id, "MMD0", 4)) || (!memcmp (id, "MMD1", 4)))    return 1;  return 0;}BOOL MED_Init (void){  if (!(me = (MEDEXP *) _mm_malloc (sizeof (MEDEXP))))    return 0;  if (!(mh = (MEDHEADER *) _mm_malloc (sizeof (MEDHEADER))))    return 0;  if (!(ms = (MEDSONG *) _mm_malloc (sizeof (MEDSONG))))    return 0;  return 1;}void MED_Cleanup (void){  _mm_free (me);  _mm_free (mh);  _mm_free (ms);  _mm_free (ba);  _mm_free (mmd0pat);  _mm_free (mmd1pat);}static void EffectCvt (UBYTE eff, UBYTE dat){  switch (eff)    {      /* 0x0 0x1 0x2 0x3 0x4 PT effects */    case 0x5:			/* PT vibrato with speed/depth nibbles swapped */      UniPTEffect (0x4, (dat >> 4) | ((dat & 0xf) << 4));      break;      /* 0x6 0x7 not used */    case 0x6:    case 0x7:      break;    case 0x8:			/* midi hold/decay */      break;    case 0x9:      if (bpmtempos)	{	  if (!dat)	    dat = of.initspeed;	  UniEffect (UNI_S3MEFFECTA, dat);	}      else	{	  if (dat <= 0x20)	    {	      if (!dat)		dat = of.initspeed;	      else		dat /= 4;	      UniPTEffect (0xf, dat);	    }	  else	    UniEffect (UNI_MEDSPEED, ((UWORD) dat * 125) / (33 * 4));	}      break;      /* 0xa 0xb PT effects */    case 0xc:      if (decimalvolumes)	dat = (dat >> 4) * 10 + (dat & 0xf);      UniPTEffect (0xc, dat);      break;    case 0xd:			/* same as PT volslide */      UniPTEffect (0xa, dat);      break;    case 0xe:			/* synth jmp - midi */      break;    case 0xf:      switch (dat)	{	case 0:		/* patternbreak */	  UniPTEffect (0xd, 0);	  break;	case 0xf1:		/* play note twice */	  UniWriteByte (UNI_MEDEFFECTF1);	  break;	case 0xf2:		/* delay note */	  UniWriteByte (UNI_MEDEFFECTF2);	  break;	case 0xf3:		/* play note three times */	  UniWriteByte (UNI_MEDEFFECTF3);	  break;	case 0xfe:		/* stop playing */	  UniPTEffect (0xb, of.numpat);	  break;	case 0xff:		/* note cut */	  UniPTEffect (0xc, 0);	  break;	default:	  if (dat <= 10)	    UniPTEffect (0xf, dat);	  else if (dat <= 240)	    {	      if (bpmtempos)		UniPTEffect (0xf, (dat < 32) ? 32 : dat);	      else		UniEffect (UNI_MEDSPEED, ((UWORD) dat * 125) / 33);	    }	}      break;    default:			/* all normal PT effects are handled here */      UniPTEffect (eff, dat);      break;    }}static UBYTE *MED_Convert1 (int count, int col){  int t;  UBYTE inst, note, eff, dat;  MMD1NOTE *n;  UniReset ();  for (t = 0; t < count; t++)    {      n = &d1note (t, col);      note = n->a & 0x7f;      inst = n->b & 0x3f;      eff = n->c & 0xf;      dat = n->d;      if (inst)	UniInstrument (inst - 1);      if (note)	UniNote (note + 3 * OCTAVE - 1);      EffectCvt (eff, dat);      UniNewline ();    }  return UniDup ();}static UBYTE *MED_Convert0 (int count, int col){  int t;  UBYTE a, b, inst, note, eff, dat;  MMD0NOTE *n;  UniReset ();  for (t = 0; t < count; t++)    {      n = &d0note (t, col);      a = n->a;      b = n->b;      note = a & 0x3f;      a >>= 6;      a = ((a & 1) << 1) | (a >> 1);      inst = (b >> 4) | (a << 4);      eff = b & 0xf;      dat = n->c;      if (inst)	UniInstrument (inst - 1);      if (note)	UniNote (note + 3 * OCTAVE - 1);      EffectCvt (eff, dat);      UniNewline ();    }  return UniDup ();}static BOOL LoadMMD0Patterns (void){  int t, row, col;  UWORD numtracks, numlines, maxlines = 0, track = 0;  MMD0NOTE *mmdp;  /* first, scan patterns to see how many channels are used */  for (t = 0; t < of.numpat; t++)    {      _mm_fseek (modreader, ba[t], SEEK_SET);      numtracks = _mm_read_UBYTE (modreader);      numlines = _mm_read_UBYTE (modreader);      if (numtracks > of.numchn)	of.numchn = numtracks;      if (numlines > maxlines)	maxlines = numlines;    }  of.numtrk = of.numpat * of.numchn;  if (!AllocTracks ())    return 0;  if (!AllocPatterns ())    return 0;  if (!(mmd0pat = (MMD0NOTE *) _mm_calloc (of.numchn * (maxlines + 1), sizeof (MMD0NOTE))))    return 0;  /* second read: read and convert patterns */  for (t = 0; t < of.numpat; t++)    {      _mm_fseek (modreader, ba[t], SEEK_SET);

⌨️ 快捷键说明

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