public void GenerateSamples(int fullSamples, int ticksPerSample) { int fullSampleCount = fullSamples; while (fullSampleCount > 0) { // We how many ticks will pass this sample long ticks = ticksPerSample; // If the event already run, we try to see if there is a new one if (_outputState.EventAlreadyRun) { if (_soundEventQueue.GetNextEvent(ref _outputState.CurrentEvent)) { _outputState.EventTickCounter = _outputState.CurrentEvent.TickDiff; _outputState.EventAlreadyRun = false; } else { _outputState.EventOnHoldCounter += ticks; } } else { // We need to substract the on hold time _outputState.EventOnHoldCounter += ticks; if (_outputState.EventTickCounter > _outputState.EventOnHoldCounter) { _outputState.EventTickCounter -= _outputState.EventOnHoldCounter; } else { _outputState.EventTickCounter = 0; } _outputState.EventOnHoldCounter = 0; if (_outputState.EventTickCounter <= 0) { HandleSoundEvent(); } } // We simulate to output the output int volume = 0; if (_state.Enabled) { _outputState.SampleTimerDivider -= ticks; while (_outputState.SampleTimerDivider <= 0) { _outputState.SampleTimerDivider += 32; --_outputState.SampleTickCounter; if (_outputState.SampleTickCounter <= 0) { _outputState.SampleTickCounter += _outputState.SampleTickThreshold; _outputState.SampleUp = !_outputState.SampleUp; } } volume = _outputState.SampleVolume; } // We generate the sample for (int c = 0; c < NumChannels; ++c) { _buffer[_outputState.SampleIndex++] = (short)(_outputState.SampleUp ? volume : -volume); } --fullSampleCount; } }
public void GenerateSamples(int sampleCount, int ticksPerSample) { while (sampleCount > 0) { --sampleCount; // We how many ticks will pass this sample long eventTicks = ticksPerSample; eventTicks += _outputState.EventOnHoldCounter; _outputState.EventOnHoldCounter = 0; while (eventTicks > 0) { // If the event already run, we try to see if there is a new one if (_outputState.EventAlreadyRun) { if (_soundEventQueue.GetNextEvent(ref _outputState.CurrentEvent)) { _outputState.EventTickCounter = _outputState.CurrentEvent.TickDiff; _outputState.EventAlreadyRun = false; } else { _outputState.EventOnHoldCounter += eventTicks; eventTicks = 0; } } else { // We need to substract the on hold time if (_outputState.EventTickCounter > eventTicks) { _outputState.EventTickCounter -= eventTicks; eventTicks = 0; } else { eventTicks -= _outputState.EventTickCounter; _outputState.EventTickCounter = 0; } if (_outputState.EventTickCounter <= 0) { HandleSoundEvent(); } } } // We simulate int ticks = ticksPerSample; _outputState.SampleClockDividerCounter -= ticks; while (_outputState.SampleClockDividerCounter <= 0) { _outputState.SampleClockDividerCounter += _outputState.SampleClockDividerThreshold; --_outputState.SampleClockPreScalerCounter; if (_outputState.SampleClockPreScalerCounter <= 0) { _outputState.SampleClockPreScalerCounter += _outputState.SampleClockPreScalerThreshold; // We remember the last value int firstBit = _outputState.SampleLsfrRegister & 0x01; bool prevSampleUp = _outputState.SampleUp; _outputState.SampleUp = (firstBit == 0); // The last bit is inverted _outputState.SampleValue = (short)(_outputState.SampleUp ? _outputState.SampleVolume : -_outputState.SampleVolume); _outputState.SampleLsfrRegister >>= 1; // We are only interested in XOR'ing the last two bits int newDigit = (firstBit ^ _outputState.SampleLsfrRegister) & 0x01; // We insert the digit in its place if (_outputState.SampleLsfrBigSteps) { // If bit steps, as we did a shift, the 15 place is 0 _outputState.SampleLsfrRegister |= (newDigit << 14); } else { // In this case we have to clear the bit 7 first _outputState.SampleLsfrRegister = (_outputState.SampleLsfrRegister & ~0x40) | (newDigit << 6); } } } // We output for (int c = 0; c < NumChannels; ++c) { _buffer[_outputState.SampleIndex++] = _outputState.SampleValue; } } }
public void GenerateSamples(int fullSamples, int ticksPerSample) { int fullSampleCount = fullSamples; while (fullSampleCount > 0) { // We how many ticks will pass this sample long eventTicks = ticksPerSample; eventTicks += _outputState.EventOnHoldCounter; _outputState.EventOnHoldCounter = 0; while (eventTicks > 0) { // If the event already run, we try to see if there is a new one if (_outputState.EventAlreadyRun) { if (_soundEventQueue.GetNextEvent(ref _outputState.CurrentEvent)) { _outputState.EventTickCounter = _outputState.CurrentEvent.TickDiff; _outputState.EventAlreadyRun = false; } else { _outputState.EventOnHoldCounter += eventTicks; eventTicks = 0; } } else { // We need to substract the on hold time if (_outputState.EventTickCounter > eventTicks) { _outputState.EventTickCounter -= eventTicks; eventTicks = 0; } else { eventTicks -= _outputState.EventTickCounter; _outputState.EventTickCounter = 0; } if (_outputState.EventTickCounter <= 0) { HandleSoundEvent(); } } } long ticks = ticksPerSample; // We simulate to output the output if (_outputState.SampleEnabled) { _outputState.SampleTimerDivider -= ticks; while (_outputState.SampleTimerDivider <= 0) { _outputState.SampleTimerDivider += 4; --_outputState.SampleTickCounter; if (_outputState.SampleTickCounter <= 0) { _outputState.SampleTickCounter += _outputState.SampleTickThreshold; ++_outputState.SampleWaveIndex; if (_outputState.SampleWaveIndex >= 32) { _outputState.SampleWaveIndex = 0; } // We get the memory value byte currentByte = _outputState.SampleArray[_outputState.SampleWaveIndex >> 1]; if ((_outputState.SampleWaveIndex & 1) == 0) { _outputState.NewCurrentSample = (byte)(currentByte >> 4); } else { _outputState.NewCurrentSample = (byte)(currentByte & 0x0F); } _outputState.SampleVolume = CalculateWaveVolume(_outputState.NewVolumeShift, _outputState.NewCurrentSample); } } } int volume = 0; if (_outputState.SampleEnabled) { volume = _outputState.SampleVolume; } // We generate the sample for (int c = 0; c < NumChannels; ++c) { _buffer[_outputState.SampleIndex++] = (short)(volume); } --fullSampleCount; } }