public void UpdatePSG(PSGWrapper psg, int chn) { if (note == VirtualKeyboard.Note.None || note == VirtualKeyboard.Note.NoteOff) { psg.SetAttenuation(chn, 0); return; } if (!samplePlayback) { psg.SetAttenuation(chn, GetCurrentVol( )); } if (!m_UpdatedFrequency || (updatesFrequency && !samplePlayback)) { if (chn < 3) { if (!samplePlayback) { psg.SetNote(chn, GetNoteOffset(( int )note), octave, GetFreqOffset()); } else { psg.SetFrequency(chn, 1); } } else if (!samplePlayback) { int chn2, fb; chn2 = (noiseMode [m_NoiseCounter] & 0x2); fb = (noiseMode [m_NoiseCounter] & 0x1); if (chn2 == 0) { int cmd = 0xE0 | ((fb > 0 ? 4 : 0)) | ((GetNoteOffset(( int )note) - 1) % 3); //Debug.Log ( System.Convert.ToString ( cmd, 2 ) ); psg.PSGDirectWrite(cmd); } else { psg.PSGDirectWrite(fb > 0 ? 0xE7 : 0xE3); psg.SetNote(2, GetNoteOffset(( int )note), octave, GetFreqOffset()); } } } ClockInstrument(); m_UpdatedFrequency = true; }
public void SetAutoPortamento(InstrumentInstance prev, int speed) { if (speed == 0 || prev.note == VirtualKeyboard.Note.None || prev.note == VirtualKeyboard.Note.NoteOff) { return; } float prevFreq = PSGWrapper.CalculateNoteFreq((int)prev.note, prev.octave); float currFreq = PSGWrapper.CalculateNoteFreq((int)note, octave); int relFreq = (int)(prevFreq - currFreq); m_PortamentoTimer = System.Math.Abs(relFreq) / speed; portamentoSpeed = speed * System.Math.Sign(relFreq); m_AutoPortamento = true; }
public void UpdatePSGSample(PSGWrapper psg, int chn) { if (!samplePlayback) { return; } if (GetCurrentVol() == 0) { return; } if (chn == 3) { psg.PSGDirectWrite(noiseFlip ? 0xE2 : 0xE1); noiseFlip = !noiseFlip; } if (note == VirtualKeyboard.Note.None || note == VirtualKeyboard.Note.NoteOff) { psg.SetAttenuation(chn, 0); return; } if (m_SampleTimer <= 0) { m_SampleFreq = (PSGWrapper.CalculateNoteFreq(GetNoteOffset(( int )note), octave) + GetFreqOffset( )); m_SampleTimer = SAMPLE_RATE / m_SampleFreq; } float divider = SAMPLE_RATE / m_SampleFreq; float phase = (m_SampleTimer % divider) / divider; float attn = 0; int smp = 0; switch (customWaveform) { case Wave.Pulse: attn = phase < ((float)m_PWM / (float)PWM_STEPS) ? 0 : LINEAR_STEPS; smp = ( int )attn; break; case Wave.Saw: attn = Mathf.Ceil(phase * LINEAR_STEPS); smp = ( int )attn; break; case Wave.Triangle: attn = phase * LINEAR_STEPS * 2; attn = Mathf.Ceil(Mathf.Abs(attn - LINEAR_STEPS)); smp = ( int )attn; break; case Wave.Sample: if (waveTable != null) { float noteOffset = (PSGWrapper.CalculateNoteFreq(GetNoteOffset((int)note), octave) + GetFreqOffset( )) / PSGWrapper.CalculateNoteFreq(sampleRelNote + 1, 0); divider = SAMPLE_RATE / (waveTableSampleRate * noteOffset); float pos = divider - m_SampleTimer; int sampleIndex = ( int )((m_SampleTimer / divider) % waveTable.Length); if (loopSample || (m_SampleTimer / divider) < waveTable.Length) { smp = waveTable [sampleIndex]; } else { smp = LINEAR_STEPS; } } break; case Wave.Sine: attn = (1f + Mathf.Sin(2 * Mathf.PI * m_SampleFreq * m_SampleTimer / SAMPLE_RATE)) * 0.5f * LINEAR_STEPS; smp = ( int )attn; break; } if (customWaveform == Wave.Sample) { m_SampleTimer++; } else { m_SampleTimer--; } if (m_LastSample != LINEAR_VOLUME_TABLE [smp]) { attn = Math.Max(0, LINEAR_VOLUME_TABLE [smp] - (0xF - GetCurrentVol( ))); psg.SetAttenuation(chn, ( int )attn); } m_LastSample = LINEAR_VOLUME_TABLE [smp]; }