Voice2 GetPlayVoice(byte param) { byte channelNum = (byte)(_lastMidiCommand & 0x0F); var curVoice = _midiChannel[channelNum]; if (curVoice != null) { Voice2 prevVoice = null; while (true) { if (curVoice.playingNote == param) { break; } prevVoice = curVoice; curVoice = curVoice.nextVoice; if (curVoice == null) { return(null); } } if (prevVoice != null) { prevVoice.nextVoice = curVoice.nextVoice; } else { _midiChannel[channelNum] = curVoice.nextVoice; } } return(curVoice); }
static Voice2[] CreateVoices() { var voices = new Voice2[8]; for (int i = 0; i < voices.Length; i++) { voices[i] = new Voice2(); } return(voices); }
void ProcessRelease(Voice2 channel) { int newVolume = channel.curVolume - channel.releaseRate; if (newVolume < 0) { newVolume = 0; } channel.curVolume = (byte)newVolume; ProcessVibrato(channel); }
void ProcessAttack(Voice2 channel) { int newVolume = channel.curVolume + channel.attackRate; if (newVolume > channel.maxAmpl) { channel.curVolume = channel.maxAmpl; channel.nextProcessState = EnvelopeState.Decay; } else { channel.curVolume = (byte)newVolume; } ProcessVibrato(channel); }
void ProcessDecay(Voice2 channel) { int newVolume = channel.curVolume - channel.decayRate; if (newVolume <= channel.sustainRate) { channel.curVolume = channel.sustainRate; channel.nextProcessState = EnvelopeState.Sustain; } else { channel.curVolume = (byte)newVolume; } ProcessVibrato(channel); }
void ProcessSustain(Voice2 channel) { if (channel.unkVibratoRate != 0) { short volume = (short)(channel.curVolume + channel.unkRate); if ((volume & 0xFF00) != 0) { volume = (sbyte)(volume >> 8); volume = (short)-volume; } channel.curVolume = (byte)volume; --channel.unkCount; if (channel.unkCount == 0) { channel.unkRate = (sbyte)-channel.unkRate; channel.unkCount = (sbyte)((channel.unkVibratoDepth & 0x0F) << 1); } } ProcessVibrato(channel); }
void PlayVoice() { if (_outputTableReady != 0) { PlayMusicChips(); _outputTableReady = 0; } _octaveMask = 0xF0; Voice2 voice = null; for (int i = 0; i < 8; ++i) { voice = _cmsVoices[i]; _octaveMask = (byte)~_octaveMask; if (voice.chanNumber != 0xFF) { ProcessChannel(voice); } else { if (voice.curVolume == 0) { voice.amplitudeOutput(0); } int volume = voice.curVolume - voice.releaseRate; if (volume < 0) { volume = 0; } voice.curVolume = (byte)volume; voice.amplitudeOutput((byte)(((volume >> 4) | (volume & 0xF0)) & voice.channel)); ++_outputTableReady; } } }
void ProcessChannel(Voice2 channel) { ++_outputTableReady; switch (channel.nextProcessState) { case EnvelopeState.Attack: ProcessAttack(channel); break; case EnvelopeState.Decay: ProcessDecay(channel); break; case EnvelopeState.Sustain: ProcessSustain(channel); break; case EnvelopeState.Release: ProcessRelease(channel); break; } }
Voice2 GetFreeVoice() { Voice2 curVoice = null; Voice2 selected = null; byte volume = 0xFF; for (int i = 0; i < 8; ++i) { curVoice = _cmsVoices[i]; if (curVoice.chanNumber == 0xFF) { if (curVoice.curVolume == 0) { selected = curVoice; break; } if (curVoice.curVolume < volume) { selected = curVoice; volume = selected.curVolume; } } } if (selected != null) { selected.chanNumber = (byte)(_lastMidiCommand & 0x0F); byte channel = selected.chanNumber; var oldChannel = _midiChannel[channel]; _midiChannel[channel] = selected; selected.nextVoice = oldChannel; } return(selected); }
void ProcessVibrato(Voice2 channel) { if (channel.vibratoRate != 0) { short temp = (short)(channel.curFreq + channel.curVibratoRate); channel.curOctave += (byte)((temp & 0xFF00) >> 8); channel.curFreq = (byte)(temp & 0xFF); --channel.curVibratoUnk; if (channel.curVibratoUnk == 0) { channel.curVibratoRate = (sbyte)(-channel.curVibratoRate); channel.curVibratoUnk = (sbyte)((channel.vibratoDepth & 0x0F) << 1); } } var output = channel.amplitudeOutput; output((byte)(((channel.curVolume >> 4) | (channel.curVolume & 0xF0)) & channel.channel)); output = channel.freqOutput; output(channel.curFreq); output = channel.octaveOutput; output((byte)((((channel.curOctave << 4) | (channel.curOctave & 0x0F)) & _octaveMask) | ((~_octaveMask) & channel.octaveInput()))); }
static Voice2[] CreateVoices() { var voices = new Voice2[8]; for (int i = 0; i < voices.Length; i++) { voices[i] = new Voice2(); } return voices; }
void ProcessRelease(Voice2 channel) { int newVolume = channel.curVolume - channel.releaseRate; if (newVolume < 0) newVolume = 0; channel.curVolume = (byte)newVolume; ProcessVibrato(channel); }