示例#1
0
    void SynthesizeChannel(ChannelState& dst, AYM::ChannelBuilder& channel, AYM::TrackBuilder& track)
    {
      if (!dst.Enabled)
      {
        channel.SetLevel(0);
        return;
      }

      const Sample& curSample = Data->Samples.Get(dst.SampleNum);
      const Sample::Line& curSampleLine = curSample.GetLine(dst.PosInSample);
      const Ornament& curOrnament = Data->Ornaments.Get(dst.OrnamentNum);

      //apply tone
      const int_t halftones = int_t(dst.Note) + curOrnament.GetLine(dst.PosInOrnament);
      channel.SetTone(halftones, dst.Sliding + curSampleLine.Vibrato);
      if (curSampleLine.ToneMask)
      {
        channel.DisableTone();
      }
      //apply level
      channel.SetLevel(GetVolume(dst.Volume, curSampleLine.Level));
      //apply envelope
      if (dst.Envelope)
      {
        channel.EnableEnvelope();
      }
      //apply noise
      if (!curSampleLine.NoiseMask)
      {
        track.SetNoise(curSampleLine.Noise + dst.NoiseAdd);
      }
      else
      {
        channel.DisableNoise();
      }

      //recalculate gliss
      if (dst.SlidingTargetNote != LIMITER)
      {
        const int_t absoluteSlidingRange = track.GetSlidingDifference(dst.Note, dst.SlidingTargetNote);
        const int_t realSlidingRange = absoluteSlidingRange - (dst.Sliding + dst.Glissade);

        if ((dst.Glissade > 0 && realSlidingRange <= 0) ||
            (dst.Glissade < 0 && realSlidingRange >= 0))
        {
          dst.Note = dst.SlidingTargetNote;
          dst.SlidingTargetNote = LIMITER;
          dst.Sliding = dst.Glissade = 0;
        }
      }
      dst.Sliding += dst.Glissade;

      if (++dst.PosInSample >= curSample.GetSize())
      {
        dst.PosInSample = curSample.GetLoop();
      }
      if (++dst.PosInOrnament >= curOrnament.GetSize())
      {
        dst.PosInOrnament = curOrnament.GetLoop();
      }
    }
示例#2
0
 void GetNewChannelState(const Cell& src, ChannelState& dst, AYM::TrackBuilder& track)
 {
   if (const bool* enabled = src.GetEnabled())
   {
     dst.Enabled = *enabled;
   }
   dst.VolSlideCounter = 0;
   dst.SlidingSteps = 0;
   bool contSample = false, contOrnament = false;
   bool reloadNote = false;
   for (CommandsIterator it = src.GetCommands(); it; ++it)
   {
     switch (it->Type)
     {
     case ENVELOPE:
       if (-1 != it->Param1)
       {
         track.SetEnvelopeType(it->Param1);
       }
       if (-1 != it->Param2)
       {
         EnvelopeTone = it->Param2;
         track.SetEnvelopeTone(EnvelopeTone);
       }
       break;
     case ENVELOPE_ON:
       dst.Envelope = true;
       break;
     case ENVELOPE_OFF:
       dst.Envelope = false;
       break;
     case NOISE:
       dst.BaseNoise = it->Param1;
       break;
     case CONT_SAMPLE:
       contSample = true;
       break;
     case CONT_ORNAMENT:
       contOrnament = true;
       break;
     case GLISS:
       dst.Glissade = it->Param1;
       dst.SlidingSteps = -1;//infinite sliding
       break;
     case SLIDE:
     {
       dst.SlidingSteps = it->Param1;
       const int_t newSliding = (dst.Sliding | 0xf) ^ 0xf;
       dst.Glissade = -newSliding / (dst.SlidingSteps ? dst.SlidingSteps : 1);
       dst.Sliding = dst.Glissade * dst.SlidingSteps;
       break;
     }
     case SLIDE_NOTE:
     {
       dst.SlidingSteps = it->Param1;
       dst.SlidingTargetNote = it->Param2;
       const int_t absoluteSliding = track.GetSlidingDifference(dst.Note, dst.SlidingTargetNote);
       const int_t newSliding = absoluteSliding - (contSample ? dst.Sliding / 16 : 0);
       dst.Glissade = 16 * newSliding / (dst.SlidingSteps ? dst.SlidingSteps : 1);
       reloadNote = true;
       break;
     }
     case AMPLITUDE_SLIDE:
       dst.VolSlideCounter = dst.VolSlideDelay = it->Param1;
       dst.VolSlideAddon = it->Param2;
       break;
     case BREAK_SAMPLE:
       dst.BreakSample = true;
       break;
     default:
       assert(!"Invalid cmd");
       break;
     }
   }
   if (const uint_t* ornament = src.GetOrnament())
   {
     dst.OrnamentNum = *ornament;
   }
   if (const uint_t* sample = src.GetSample())
   {
     dst.SampleNum = *sample;
   }
   if (const uint_t* note = src.GetNote())
   {
     dst.Note = *note;
     reloadNote = true;
   }
   if (reloadNote)
   {
     dst.CurrentNoise = dst.BaseNoise;
     if (dst.SlidingSteps <= 0)
     {
       dst.Sliding = 0;
     }
     if (!contSample)
     {
       dst.CurrentSampleNum = dst.SampleNum;
       dst.PosInSample = 0;
       dst.VolumeAddon = 0;
       dst.ToneDeviation = 0;
       dst.BreakSample = false;
     }
     if (!contOrnament)
     {
       dst.CurrentOrnamentNum = dst.OrnamentNum;
       dst.PosInOrnament = 0;
       dst.NoteAddon = 0;
     }
   }
   if (const uint_t* volume = src.GetVolume())
   {
     dst.Volume = *volume;
   }
 }
示例#3
0
 void GetNewChannelState(const Cell& src, ChannelState& dst, AYM::TrackBuilder& track)
 {
   if (const bool* enabled = src.GetEnabled())
   {
     if (*enabled)
     {
       dst.SampleIterator.Reset();
     }
     else
     {
       dst.SampleIterator.Disable();
     }
     dst.SampleNoiseAccumulator.Reset();
     dst.VolumeSlide = 0;
     dst.NoiseAccumulator.Reset();
     dst.NoteAccumulator.Reset();
     dst.OrnamentIterator.Reset();
     dst.ToneAccumulator.Reset();
     dst.EnvelopeAccumulator.Reset();
     dst.ToneSlide.Reset();
   }
   if (const uint_t* note = src.GetNote())
   {
     dst.Note = *note + Transposition;
   }
   if (const uint_t* sample = src.GetSample())
   {
     dst.SampleIterator.Set(Data->Samples.Get(*sample));
   }
   if (const uint_t* ornament = src.GetOrnament())
   {
     dst.OrnamentIterator.Set(Data->Ornaments.Get(*ornament));
     dst.OrnamentIterator.Reset();
     dst.NoiseAccumulator.Reset();
     dst.NoteAccumulator.Reset();
   }
   if (const uint_t* volume = src.GetVolume())
   {
     dst.Volume = *volume;
   }
   for (CommandsIterator it = src.GetCommands(); it; ++it)
   {
     switch (it->Type)
     {
     case ENVELOPE:
       track.SetEnvelopeType(it->Param1);
       dst.Envelope = it->Param2;
       dst.EnvelopeEnabled = true;
       break;
     case ENVELOPE_OFF:
       dst.EnvelopeEnabled = false;
       break;
     case NOISE:
       dst.Noise = it->Param1;
       break;
     case SLIDE:
       dst.ToneSlide.SetGlissade(it->Param1);
       break;
     case SLIDE_NOTE:
       {
         const int_t slide = track.GetSlidingDifference(it->Param2, dst.Note);
         const int_t gliss = slide >= 0 ? -it->Param1 : it->Param1;
         const int_t direction = slide >= 0 ? -1 : +1;
         dst.ToneSlide.SetSlide(slide);
         dst.ToneSlide.SetGlissade(gliss);
         dst.ToneSlide.SetSlideDirection(direction);
         dst.Note = it->Param2 + Transposition;
       }
       break;
     }
   }
 }