예제 #1
0
파일: hsc.cpp 프로젝트: OPLx/adplug
void ChscPlayer::rewind(int subsong)
{
  int i;								// counter

  // rewind HSC player
  pattpos = 0; songpos = 0; pattbreak = 0; speed = 2;
  del = 1; songend = 0; mode6 = 0; bd = 0; fadein = 0;

  opl->init();						// reset OPL chip
  opl->write(1,32); opl->write(8,128); opl->write(0xbd,0);

  for(i=0;i<9;i++)
    setinstr((char) i,(char) i);	// init channels
}
예제 #2
0
파일: cremid6.c 프로젝트: jbailhache/log
int cremid (char *buf, char *partition)
{
int i, n, rec;
char cmd;
char *ptr;
 ptr = buf;
 for (i=0; i<strlen(partition); i++)
 {
  cmd = partition[i];

  if (cmd >= 'A' && cmd <= 'P')
   canal = cmd - 'A';
  else if (cmd >= '0' && cmd <= '9')
   octave = cmd - '0';
  else if (cmd == '(')
   garde = 1;
  else if (cmd == '*')
   niveau++;
  else if (cmd == '$')
  {
   n = sp;
   canal = pile[n-1-niveau].canal;
   freq = pile[n-1-niveau].freq;
   ptr += delay (ptr, 0);
   ptr += noteoff (ptr, canal, freq);
   niveau = 0;
  }
  else if (cmd == ';')
  {
   ptr += delay (ptr, tempo1);
   ptr += noteoff (ptr, canal1, numnote1);
   numnote1 = -1;
  }
  else if (cmd == ')')
  {
   ptr += delay (ptr, tempo1);
   ptr += noteoff (ptr, canal1, numnote1);
   numnote1 = 0;
   i++;
   note = partition[i] - 'a';
   numnote = num_note (note, octave);
   ptr += delay (ptr, 0);
   ptr += noteoff (ptr, canal, numnote);
  }
  else if (cmd == ':')
  {
   instrument = 100 * (partition[i+1]-'0') + 10 * (partition[i+2]-'0') + partition[i+3]-'0';
   ptr += delay (ptr, 0);
   ptr += setinstr (ptr, canal, instrument);
   i += 3;
  }
  else if (cmd == '!')
  {
   volume = 100 * (partition[i+1]-'0') + 10 * (partition[i+2]-'0') + partition[i+3]-'0';
   i += 3;
  }
  else if (cmd == ',')
  {
   tempo *= vt;
   volume *= va;
   if (garde == 0)
   {
    int j;
    for (j=0; j<naccord; j++)
    {
     numnote2 = accord[j];
     if (numnote2 > 0)
     {
      char d[10];
      int ld;
      if (j == 0)
       ld = delay (d, tempo1);
      else
      {
       ld = 1;
       d[0] = 0;
      }
      memcpy (ptr, d, ld);
      ptr += ld;
      ptr += noteoff (ptr, canal, numnote2);
     }
    }
   }
   naccord = 0;
  }
  else if (cmd >= 'a' && cmd <= 'z')
  {
   note = cmd - 'a' + shift;
   if (!accords)
   {
    tempo *= vt;
    volume *= va;
   }
   numnote = num_note (note, octave);
   if (!garde && numnote1 > 0 && !accords)
   {
    ptr += delay (ptr, tempo1);
    ptr += noteoff (ptr, canal1, numnote1);
   }
   if (numnote1 == -1)
    silence = tempo1;
   ptr += delay (ptr, silence);
   ptr += noteon (ptr, canal, numnote, volume); /***/
   if (accords == 1)
   {
    accord[naccord++] = numnote;
   }
   if (garde)
   {
    pile[sp].canal = canal;
    pile[sp].freq = numnote;
    sp++;
   }
   tempo1 = tempo;
   garde = 0;
   silence = 0;
   canal1 = canal;
   numnote1 = numnote;
  }
  else if (cmd == 'W')
  {
   silence = tempo1;
   tempo1 = tempo;
  }
  else if (cmd == 'T')
  {
   tempo = 100 * (partition[i+1]-'0') + 10 * (partition[i+2]-'0') + partition[i+3]-'0';
   i += 3;
  }
  else if (cmd == 'S')
  {
   shift = 100 * (partition[i+1]-'0') + 10 * (partition[i+2]-'0') + partition[i+3]-'0';
   i += 3;
  }
  else if (cmd == 'V')
  {
   char b[6];
   float x;
   v = partition[i+1];
   memcpy (b, partition+i+2, 5);
   b[5] = 0;
   sscanf (b, "%f", &x);
   if (v == 'T')
    vt = x;
   else if (v == '!')
    va = x;
   i += 6;
  }
  else if (cmd == '^')
  {
   mode = partition[i+1];
   i++;
   if (mode == 'A')
    accords = 1;
   else if (mode == '1')
    accords = 0;
  }
  else if (cmd == 'U')
  {
   i++;
   if (partition[i] == '_')
    tempo *= 2;
   else if (partition[i] == '\'')
    tempo /= 2;
   else if (partition[i] == '+')
   {
    i++;
    tempo += 100 * (partition[i] - '0');
   }
   else if (partition[i] == '-')
   {
    i++;
    tempo -= 100 * (partition[i] - '0');
   }
  }
  else if (cmd == '_')
   tempo1 *= 2;
  else if (cmd == '\'')
   tempo1 /= 2;
  else if (cmd == '+')
  {
   i++;
   tempo1 += 100 * (partition[i] - '0');
  }
  else if (cmd == '-')
  {
   i++;
   tempo1 -= 100 * (partition[i] - '0');
  }

 }

 ptr += delay (ptr, tempo1);
 ptr += noteoff (ptr, canal1, numnote1);

 ptr += delay (ptr, 0);

 memcpy (ptr, "\xFF\x2F\x00", 3);
 ptr += 3;

 return ptr-buf;
}
예제 #3
0
파일: hsc.cpp 프로젝트: OPLx/adplug
bool ChscPlayer::update()
{
  // general vars
  unsigned char		chan,pattnr,note,effect,eff_op,inst,vol,Okt,db;
  unsigned short	Fnr;
  unsigned long		pattoff;

  del--;                      // player speed handling
  if(del)
    return !songend;		// nothing done

  if(fadein)					// fade-in handling
    fadein--;

  pattnr = song[songpos];
  // 0xff indicates song end, but this prevents a crash for some songs that
  // use other weird values, like 0xbf
  if(pattnr >= 0xb2) {			// arrangement handling
    songend = 1;				// set end-flag
    songpos = 0;
    pattnr = song[songpos];
  } else
    if ((pattnr & 128) && (pattnr <= 0xb1)) { // goto pattern "nr"
      songpos = song[songpos] & 127;
      pattpos = 0;
      pattnr = song[songpos];
      songend = 1;
    }

  pattoff = pattpos*9;
  for (chan=0;chan<9;chan++) {			// handle all channels
    note = patterns[pattnr][pattoff].note;
    effect = patterns[pattnr][pattoff].effect;
    pattoff++;

    if(note & 128) {                    // set instrument
      setinstr(chan,effect);
      continue;
    }
    eff_op = effect & 0x0f;
    inst = channel[chan].inst;
    if(note)
      channel[chan].slide = 0;

    switch (effect & 0xf0) {			// effect handling
    case 0:								// global effect
      /* The following fx are unimplemented on purpose:
       * 02 - Slide Mainvolume up
       * 03 - Slide Mainvolume down (here: fade in)
       * 04 - Set Mainvolume to 0
       *
       * This is because i've never seen any HSC modules using the fx this way.
       * All modules use the fx the way, i've implemented it.
       */
      switch(eff_op) {
      case 1: pattbreak++; break;	// jump to next pattern
      case 3: fadein = 31; break;	// fade in (divided by 2)
      case 5: mode6 = 1; break;	// 6 voice mode on
      case 6: mode6 = 0; break;	// 6 voice mode off
      }
      break;
    case 0x20:
    case 0x10:		                    // manual slides
      if (effect & 0x10) {
	channel[chan].freq += eff_op;
	channel[chan].slide += eff_op;
      } else {
	channel[chan].freq -= eff_op;
	channel[chan].slide -= eff_op;
      }
      if(!note)
	setfreq(chan,channel[chan].freq);
      break;
    case 0x50:							// set percussion instrument (unimplemented)
      break;
    case 0x60:							// set feedback
      opl->write(0xc0 + chan, (instr[channel[chan].inst][8] & 1) + (eff_op << 1));
      break;
    case 0xa0:		                    // set carrier volume
      vol = eff_op << 2;
      opl->write(0x43 + op_table[chan], vol | (instr[channel[chan].inst][2] & ~63));
      break;
    case 0xb0:		                    // set modulator volume
      vol = eff_op << 2;
      if (instr[inst][8] & 1)
	opl->write(0x40 + op_table[chan], vol | (instr[channel[chan].inst][3] & ~63));
      else
	opl->write(0x40 + op_table[chan],vol | (instr[inst][3] & ~63));
      break;
    case 0xc0:		                    // set instrument volume
      db = eff_op << 2;
      opl->write(0x43 + op_table[chan], db | (instr[channel[chan].inst][2] & ~63));
      if (instr[inst][8] & 1)
	opl->write(0x40 + op_table[chan], db | (instr[channel[chan].inst][3] & ~63));
      break;
    case 0xd0: pattbreak++; songpos = eff_op; songend = 1; break;	// position jump
    case 0xf0:							// set speed
      speed = eff_op;
      del = ++speed;
      break;
    }

    if(fadein)						// fade-in volume setting
      setvolume(chan,fadein*2,fadein*2);

    if(!note)						// note handling
      continue;
    note--;

    if ((note == 0x7f-1) || ((note/12) & ~7)) {    // pause (7fh)
      adl_freq[chan] &= ~32;
      opl->write(0xb0 + chan,adl_freq[chan]);
      continue;
    }

    // play the note
    if(mtkmode)		// imitate MPU-401 Trakker bug
      note--;
    Okt = ((note/12) & 7) << 2;
    Fnr = note_table[(note % 12)] + instr[inst][11] + channel[chan].slide;
    channel[chan].freq = Fnr;
    if(!mode6 || chan < 6)
      adl_freq[chan] = Okt | 32;
    else
      adl_freq[chan] = Okt;		// never set key for drums
    opl->write(0xb0 + chan, 0);
    setfreq(chan,Fnr);
    if(mode6) {
      switch(chan) {		// play drums
      case 6: opl->write(0xbd,bd & ~16); bd |= 48; break;	// bass drum
      case 7: opl->write(0xbd,bd & ~1); bd |= 33; break;	// hihat
      case 8: opl->write(0xbd,bd & ~2); bd |= 34; break;	// cymbal
      }
      opl->write(0xbd,bd);
    }
  }

  del = speed;		// player speed-timing
  if(pattbreak) {		// do post-effect handling
    pattpos=0;			// pattern break!
    pattbreak=0;
    songpos++;
    songpos %= 50;
    if(!songpos)
      songend = 1;
  } else {
    pattpos++;
    pattpos &= 63;		// advance in pattern data
    if (!pattpos) {
      songpos++;
      songpos %= 50;
      if(!songpos)
	songend = 1;
    }
  }
  return !songend;		// still playing
}