/// <summary> /// Frame is completed /// </summary> public void EndFrame() { // store the last pulse information if (LastPulseTState <= _tStatesPerFrame - 1) { Pulse p = new Pulse { State = LastPulse, Length = _tStatesPerFrame - LastPulseTState }; Pulses.Add(p); } // create the sample array var firstSampleOffset = _frameStart % TStatesPerSample == 0 ? 0 : TStatesPerSample - (_frameStart + TStatesPerSample) % TStatesPerSample; var samplesInFrame = (_tStatesPerFrame - firstSampleOffset - 1) / TStatesPerSample + 1; var samples = new short[samplesInFrame]; // convert pulses to samples var sampleIndex = 0; var currentEnd = _frameStart; foreach (var pulse in Pulses) { var firstSample = currentEnd % TStatesPerSample == 0 ? currentEnd : currentEnd + TStatesPerSample - currentEnd % TStatesPerSample; for (var i = firstSample; i < currentEnd + pulse.Length; i += TStatesPerSample) { samples[sampleIndex++] = pulse.State ? (short)(_volume) : (short)0; } currentEnd += pulse.Length; } // fill the _sampleBuffer for ISoundProvider soundBufferContains = (int)samplesInFrame; if (soundBuffer.Length != soundBufferContains) { soundBuffer = new short[soundBufferContains]; } samples.CopyTo(soundBuffer, 0); _frameStart += _tStatesPerFrame; }
/// <summary> /// When the pulse value changes it is processed here /// </summary> /// <param name="pulse"></param> public void ProcessPulseValue(bool pulse) { if (!_machine._renderSound) { return; } if (pulse == LastPulse) { // no change detected return; } // set the lastpulse LastPulse = pulse; // get where we are in the frame var currentULACycle = _machine.CurrentFrameCycle; var currentBuzzerCycle = currentULACycle <= _tStatesPerFrame ? currentULACycle : _tStatesPerFrame; var length = currentBuzzerCycle - LastPulseTState; if (length == 0) { // the first T-State has changed the pulse // do not add it } else if (length > 0) { // add the pulse Pulse p = new Pulse { State = !pulse, Length = length }; Pulses.Add(p); } // set the last pulse tstate LastPulseTState = currentBuzzerCycle; }