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); }
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; } }