public virtual void ChannelStep(int cycles) { if (!Active || _spu.Device.Cpu.SpeedFactor < 0.5) { return; } UpdateVolume(cycles); const float maxAmplitude = 0.05f; double realFrequency = 131072.0 / (2048.0 - Frequency) / 2; int sampleRate = ChannelOutput.SampleRate; double timeDelta = (cycles / GameBoyCpu.OfficialClockFrequency) / _spu.Device.Cpu.SpeedFactor * 2; int sampleCount = (int)(timeDelta * sampleRate); float[] buffer = new float[sampleCount]; if (!UseSoundLength || _length >= 0) { for (int i = 0; i < buffer.Length; i++) { buffer[i] = (float)(maxAmplitude * (_volume / 15.0) // Volume adjustments. * Math.Sign(Math.Sin(2 * Math.PI * realFrequency * _coordinate / sampleRate))); // Square wave formula _coordinate = (_coordinate + 1) % sampleRate; } 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); }
public virtual void ChannelStep(int cycles) { double cpuSpeedFactor = _spu.Device.Cpu.SpeedFactor; if (!Active || double.IsNaN(cpuSpeedFactor) || double.IsInfinity(cpuSpeedFactor) || cpuSpeedFactor < 0.5) { return; } UpdateVolume(cycles); double realFrequency = 131072.0 / (2048.0 - Frequency); int sampleRate = ChannelOutput.SampleRate; double timeDelta = (cycles / GameBoyCpu.OfficialClockFrequency) / cpuSpeedFactor; int sampleCount = (int)(timeDelta * sampleRate) * 2; float[] buffer = new float[sampleCount]; if (!UseSoundLength || _length >= 0) { for (int i = 0; i < buffer.Length; i += 2) { float sample = (float)(ChannelVolume * (_volume / 15.0) // Volume adjustments. * Math.Sign(Math.Sin(2 * Math.PI * realFrequency * _coordinate / sampleRate))); // Square wave formula _spu.WriteToSoundBuffer(ChannelNumber, buffer, i, sample); _coordinate = (_coordinate + 1) % sampleRate; } if (UseSoundLength) { _length -= timeDelta; } } ChannelOutput.BufferSoundSamples(buffer, 0, buffer.Length); }