示例#1
0
 public void StartPCM(SWAVInfo wave, int noteLength)
 {
     Type       = InstrumentType.PCM;
     dataOffset = 0;
     this.wave  = wave;
     if (wave.Format == SWAVFormat.ADPCM)
     {
         adpcmDecoder = new ADPCMDecoder(wave.Samples);
     }
     BaseTimer = wave.Timer;
     Start(noteLength);
 }
示例#2
0
        public void PlayNote(Track track, byte key, byte noteVelocity, int noteLength)
        {
            Channel channel = null;

            if (track.Tie && track.Channels.Count != 0)
            {
                channel              = track.Channels.Last();
                channel.Key          = key;
                channel.NoteVelocity = noteVelocity;
            }
            else
            {
                InstrumentData inst = sbnk.GetInstrumentData(track.Voice, key);
                if (inst != null)
                {
                    channel = SoundMixer.Instance.AllocateChannel(inst.Type, track);
                    if (channel != null)
                    {
                        if (track.Tie)
                        {
                            noteLength = -1;
                        }
                        int release = inst.Param.Release;
                        if (release == 0xFF)
                        {
                            noteLength = -1;
                            release    = 0;
                        }
                        bool started = false;
                        switch (inst.Type)
                        {
                        case InstrumentType.PCM:
                        {
                            SWAVInfo wave = sbnk.GetWave(inst.Param.Info[1], inst.Param.Info[0]);
                            if (wave != null)
                            {
                                channel.StartPCM(wave, noteLength);
                                started = true;
                            }
                            break;
                        }

                        case InstrumentType.PSG:
                        {
                            channel.StartPSG((byte)inst.Param.Info[0], noteLength);
                            started = true;
                            break;
                        }

                        case InstrumentType.Noise:
                        {
                            channel.StartNoise(noteLength);
                            started = true;
                            break;
                        }
                        }
                        channel.Stop();
                        if (started)
                        {
                            channel.Key          = key;
                            channel.BaseKey      = inst.Param.BaseKey;
                            channel.NoteVelocity = noteVelocity;
                            channel.SetAttack(inst.Param.Attack);
                            channel.SetDecay(inst.Param.Decay);
                            channel.SetSustain(inst.Param.Sustain);
                            channel.SetRelease(release);
                            channel.StartingPan = (sbyte)(inst.Param.Pan - 0x40);
                            channel.Owner       = track;
                            track.Channels.Add(channel);
                        }
                        else
                        {
                            return;
                        }
                    }
                }
            }
            if (channel != null)
            {
                if (track.Attack != 0xFF)
                {
                    channel.SetAttack(track.Attack);
                }
                if (track.Decay != 0xFF)
                {
                    channel.SetDecay(track.Decay);
                }
                if (track.Sustain != 0xFF)
                {
                    channel.SetSustain(track.Sustain);
                }
                if (track.Release != 0xFF)
                {
                    channel.SetRelease(track.Release);
                }
                channel.SweepPitch = track.SweepPitch;
                if (track.Portamento)
                {
                    channel.SweepPitch += (short)((track.PortamentoKey - key) << 6); // "<< 6" is "* 0x40"
                }
                if (track.PortamentoTime != 0)
                {
                    channel.SweepLength = (track.PortamentoTime * track.PortamentoTime * Math.Abs(channel.SweepPitch)) >> 11; // ">> 11" is "/ 0x800"
                    channel.AutoSweep   = true;
                }
                else
                {
                    channel.SweepLength = noteLength;
                    channel.AutoSweep   = false;
                }
                channel.SweepCounter = 0;
            }
        }