private void PlayNote(Track track, byte key, byte duration) { VoiceEntry entry = GetVoiceEntry(track.Voice, key); if (entry != null) { track.NoteDuration = duration; if (track.Index >= 8) { // TODO: "Sample" byte in VoiceEntry ((SquareChannel)track.Channel).Init(key, new ADSR { A = 0xFF, D = 0x00, S = 0xFF, R = 0x00 }, track.Volume, track.Panpot, track.GetPitch()); } else { int sto = _config.SampleTableOffset; int sampleOffset = _config.Reader.ReadInt32(sto + (entry.Sample * 4)); // Some entries are 0. If you play them, are they silent, or does it not care if they are 0? ((PCMChannel)track.Channel).Init(key, new ADSR { A = 0xFF, D = 0x00, S = 0xFF, R = 0x00 }, sto + sampleOffset, entry.IsFixedFrequency == 0x80); track.Channel.SetVolume(track.Volume, track.Panpot); track.Channel.SetPitch(track.GetPitch()); } } }
private VoiceEntry GetVoiceEntry(byte voice, byte key) { int vto = _config.VoiceTableOffset; short voiceOffset = _config.Reader.ReadInt16(vto + (voice * 2)); short nextVoiceOffset = _config.Reader.ReadInt16(vto + ((voice + 1) * 2)); if (voiceOffset == nextVoiceOffset) { return(null); } else { long pos = vto + voiceOffset; // Prevent object creation in the last iteration VoiceEntry e = _config.Reader.ReadObject <VoiceEntry>(pos); while (e.MinKey > key || e.MaxKey < key) { pos += 8; if (pos == nextVoiceOffset) { return(null); } e = _config.Reader.ReadObject <VoiceEntry>(); } return(e); } }