public void ChannelStep(int cycles) { double cpuSpeedFactor = Spu.Device.SpeedFactor; if (!Active) { return; } // Update volume. _volumeEnvelope.Update(cycles); float amplitude = ChannelVolume * _volumeEnvelope.Volume / 15.0f; // Get elapsed gameboy time. double timeDelta = (cycles / GameBoyCpu.OfficialClockFrequency) / cpuSpeedFactor; // Allocate buffer. int sampleRate = ChannelOutput.SampleRate; int sampleCount = (int)(timeDelta * sampleRate) * 2; using (var malloc = MemoryPool <float> .Shared.Rent(sampleCount)) { var buffer = malloc.Memory.Span; if (!UseSoundLength || _length >= 0) { double period = 1 / Frequency; int periodSampleCount = (int)(period * sampleRate) * 2; for (int i = 0; i < sampleCount; i += 2) { float sample = amplitude * (_lfsr.CurrentValue ? 1f : 0f); Spu.WriteToSoundBuffer(ChannelNumber, buffer, i, sample); _clock += 2; if (_clock >= periodSampleCount) { _lfsr.PerformShift(); _clock -= periodSampleCount; } } if (UseSoundLength) { _length -= timeDelta; } } ChannelOutput.BufferSoundSamples(buffer, 0, sampleCount); } }
public void ChannelStep(int cycles) { double cpuSpeedFactor = Spu.Device.Cpu.SpeedFactor; if (!Active || double.IsNaN(cpuSpeedFactor) || double.IsInfinity(cpuSpeedFactor) || cpuSpeedFactor < 0.5) { return; } // Update volume. _volumeEnvelope.Update(cycles); float amplitude = ChannelVolume * _volumeEnvelope.Volume / 15.0f; // Get elapsed gameboy time. double timeDelta = (cycles / GameBoyCpu.OfficialClockFrequency) / cpuSpeedFactor; // Allocate buffer. int sampleRate = ChannelOutput.SampleRate; int sampleCount = (int)(timeDelta * sampleRate) * 2; float[] buffer = new float[sampleCount]; if (!UseSoundLength || _length >= 0) { double period = 1 / Frequency; int periodSampleCount = (int)(period * sampleRate) * 2; for (int i = 0; i < buffer.Length; i += 2) { float sample = amplitude * (_lfsr.CurrentValue ? 1f : 0f); Spu.WriteToSoundBuffer(ChannelNumber, buffer, i, sample); _clock += 2; if (_clock >= periodSampleCount) { _lfsr.PerformShift(); _clock -= periodSampleCount; } } if (UseSoundLength) { _length -= timeDelta; } } ChannelOutput.BufferSoundSamples(buffer, 0, buffer.Length); }
public void ChannelStep(int cycles) { double cpuSpeedFactor = Spu.Device.cpu.SpeedFactor; if (!Active || !SoundEnabled || double.IsNaN(cpuSpeedFactor) || double.IsInfinity(cpuSpeedFactor) || cpuSpeedFactor < 0.5) { return; } int sampleRate = ChannelOutput.SampleRate; double timeDelta = (cycles / GameBoySpu.ClockSpeedHz) / cpuSpeedFactor; int sampleCount = (int)(timeDelta * sampleRate) * 2; float[] buffer = new float[sampleCount]; double interval = 1.0 / Frequency; int intervalSampleCount = (int)(interval * sampleRate); if (intervalSampleCount > 0) { for (int i = 0; i < buffer.Length; i += 2) { _coordinate++; if (_coordinate >= intervalSampleCount) { _top = !_top; _coordinate = 0; } int waveRamCoordinate = (int)(_coordinate / (double)intervalSampleCount * _waveRam.Length); int waveDataSample = _top ? (_waveRam[waveRamCoordinate] & 0xF) : ((_waveRam[waveRamCoordinate] >> 4) & 0xF); float sample = ChannelVolume * OutputLevel * (waveDataSample - 7) / 15f; Spu.WriteToSoundBuffer(ChannelNumber, buffer, i, sample); } } ChannelOutput.BufferSoundSamples(buffer, 0, buffer.Length); }
public void ChannelStep(int cycles) { double cpuSpeedFactor = Spu.Device.SpeedFactor; if (!Active) { return; } int sampleRate = ChannelOutput.SampleRate; double timeDelta = (cycles / GameBoyCpu.OfficialClockFrequency) / cpuSpeedFactor; int sampleCount = (int)(timeDelta * sampleRate) * 2; using (var malloc = MemoryPool <float> .Shared.Rent(sampleCount)) { var buffer = malloc.Memory.Span; double interval = 1.0 / Frequency; int intervalSampleCount = (int)(interval * sampleRate); if (intervalSampleCount > 0) { for (int i = 0; i < sampleCount; i += 2) { _coordinate++; if (_coordinate >= intervalSampleCount) { _top = !_top; _coordinate = 0; } int waveRamCoordinate = (int)(_coordinate / (double)intervalSampleCount * _waveRam.Length); int waveDataSample = _top ? (_waveRam[waveRamCoordinate] & 0xF) : ((_waveRam[waveRamCoordinate] >> 4) & 0xF); float sample = ChannelVolume * OutputLevel * (waveDataSample - 7) / 15f; Spu.WriteToSoundBuffer(ChannelNumber, buffer, i, sample); } } ChannelOutput.BufferSoundSamples(buffer, 0, sampleCount); } }
public virtual void ChannelStep(int cycles) { double cpuSpeedFactor = Spu.Device.SpeedFactor; if (!Active) { return; } // Update volume and calculate wave amplitude. _volumeEnvelope.Update(cycles); double amplitude = ChannelVolume * (_volumeEnvelope.Volume / 15.0); // Obtain elapsed gameboy time. double timeDelta = (cycles / GameBoyCpu.OfficialClockFrequency) / cpuSpeedFactor; // Allocate sound buffer. int sampleRate = ChannelOutput.SampleRate; int sampleCount = (int)Math.Ceiling(timeDelta * sampleRate) * 2; using (var malloc = MemoryPool <float> .Shared.Rent(sampleCount)) { var buffer = malloc.Memory.Span; if (!UseSoundLength || _length >= 0) { double period = 1f / Frequency; for (int i = 0; i < sampleCount; i += 2) { // Get current x coordinate and compute current sample value. double x = (double)_coordinate / sampleRate; float sample = DutyWave(amplitude, x, period); Spu.WriteToSoundBuffer(ChannelNumber, buffer, i, sample); _coordinate = (_coordinate + 1) % sampleRate; } if (UseSoundLength) { _length -= timeDelta; } } ChannelOutput.BufferSoundSamples(buffer, 0, sampleCount); } }
public virtual void ChannelStep(int cycles) { double cpuSpeedFactor = Spu.Device.cpu.SpeedFactor; if (!Active || double.IsNaN(cpuSpeedFactor) || double.IsInfinity(cpuSpeedFactor) || cpuSpeedFactor < 0.5) { return; } // Update volume and calculate wave amplitude. _volumeEnvelope.Update(cycles); double amplitude = ChannelVolume * (_volumeEnvelope.Volume / 15.0); // Obtain elapsed gameboy time. double timeDelta = (cycles / GameBoySpu.ClockSpeedHz) / cpuSpeedFactor; // Allocate sound buffer. int sampleRate = ChannelOutput.SampleRate; int sampleCount = (int)Math.Ceiling(timeDelta * sampleRate) * 2; var buffer = new float[sampleCount]; if (!UseSoundLength || _length >= 0) { double period = 1f / Frequency; for (int i = 0; i < buffer.Length; i += 2) { // Get current x coordinate and compute current sample value. double x = (double)_coordinate / sampleRate; float sample = DutyWave(amplitude, x, period); Spu.WriteToSoundBuffer(ChannelNumber, buffer, i, sample); _coordinate = (_coordinate + 1) % sampleRate; } if (UseSoundLength) { _length -= timeDelta; } } ChannelOutput.BufferSoundSamples(buffer, 0, buffer.Length); }