示例#1
0
        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);
        }
示例#2
0
        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);
        }
示例#3
0
        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);
            }
        }
示例#4
0
        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);
            }
        }
示例#5
0
        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);
        }
示例#6
0
        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);
        }