Пример #1
0
        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);
            }
        }
Пример #2
0
        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);
        }