public SfxrParams GetMutation(double mutation)
        {
            SfxrParams p = new SfxrParams(this);

            p.Mutate(mutation);
            return(p);
        }
        public void CreateSound(SfxrParams sfxrParams, int bufferSize)
        {
            _synthesizedBlocks = new Queue <SynthesizedBuffer>();

            this.BufferSize    = bufferSize;
            this.IsReadyToPlay = false;
            this.IsPlaying     = false;

            _currentSynthesizedSample = 0;

            //TODO: check out where is the sample rate for the generation??
            localParams = new SfxrParams(sfxrParams);

            Reset(true);
            CacheSamples();
        }
        public SfxrParams(SfxrParams p)
        {
            WaveType = p.WaveType;

            MasterVolume = p.MasterVolume;

            AttackTime   = p.AttackTime;
            SustainTime  = p.SustainTime;
            SustainPunch = p.SustainPunch;
            DecayTime    = p.DecayTime;

            StartFrequency = p.StartFrequency;
            MinFrequency   = p.MinFrequency;

            Slide      = p.Slide;
            DeltaSlide = p.DeltaSlide;

            VibratoDepth = p.VibratoDepth;
            VibratoSpeed = p.VibratoSpeed;

            ChangeAmount = p.ChangeAmount;
            ChangeSpeed  = p.ChangeSpeed;

            SquareDuty = p.SquareDuty;
            DutySweep  = p.DutySweep;

            RepeatSpeed = p.RepeatSpeed;

            PhaserOffset = p.PhaserOffset;
            PhaserSweep  = p.PhaserSweep;

            lpFilterCutoff      = p.lpFilterCutoff;
            lpFilterCutoffSweep = p.lpFilterCutoffSweep;
            lpFilterResonance   = p.lpFilterResonance;

            hpFilterCutoff      = p.hpFilterCutoff;
            hpFilterCutoffSweep = p.hpFilterCutoffSweep;
        }
Exemple #4
0
        public SfxrParams(SfxrParams p)
        {
            WaveType = p.WaveType;

            MasterVolume = p.MasterVolume;

            AttackTime = p.AttackTime;
            SustainTime = p.SustainTime;
            SustainPunch = p.SustainPunch;
            DecayTime = p.DecayTime;

            StartFrequency = p.StartFrequency;
            MinFrequency = p.MinFrequency;

            Slide = p.Slide;
            DeltaSlide = p.DeltaSlide;

            VibratoDepth = p.VibratoDepth;
            VibratoSpeed = p.VibratoSpeed;

            ChangeAmount = p.ChangeAmount;
            ChangeSpeed = p.ChangeSpeed;

            SquareDuty = p.SquareDuty;
            DutySweep = p.DutySweep;

            RepeatSpeed = p.RepeatSpeed;

            PhaserOffset = p.PhaserOffset;
            PhaserSweep = p.PhaserSweep;

            lpFilterCutoff = p.lpFilterCutoff;
            lpFilterCutoffSweep = p.lpFilterCutoffSweep;
            lpFilterResonance = p.lpFilterResonance;

            hpFilterCutoff = p.hpFilterCutoff;
            hpFilterCutoffSweep = p.hpFilterCutoffSweep;
        }
Exemple #5
0
        public SoundEffect CreateSound(SfxrParams sfxrParams)
        {
            localParams = new SfxrParams(sfxrParams);

            Reset(true);

            int[] samples = new int[(int)envelopeFullLength];
            int samplesInBuffer = 0;

            bool finished = false;

            for (int i = 0; i < samples.Length; i++)
            {
                if (finished)
                    break;

                // Repeats every _repeatLimit times, partially resetting the sound parameters
                if(repeatLimit != 0)
                {
                    if(++repeatTime >= repeatLimit)
                    {
                        repeatTime = 0;
                        Reset(false);
                    }
                }

                // If _changeLimit is reached, shifts the pitch
                if(changeLimit != 0)
                {
                    if(++changeTime >= changeLimit)
                    {
                        changeLimit = 0;
                        period *= changeAmount;
                    }
                }

                // Acccelerate and apply slide
                slide += deltaSlide;
                period *= slide;

                // Checks for frequency getting too low, and stops the sound if a minFrequency was set
                if(period > maxPeriod)
                {
                    period = maxPeriod;
                    if(minFrequency > 0.0)
                        finished = true;
                }

                periodTemp = period;

                // Applies the vibrato effect
                if(vibratoAmplitude > 0.0)
                {
                    vibratoPhase += vibratoSpeed;
                    periodTemp = period * (float)(1.0 + Math.Sin(vibratoPhase) * vibratoAmplitude);
                }

                periodTemp = (int)periodTemp;
                if(periodTemp < 8)
                    periodTemp = 8;

                // Sweeps the square duty
                if (waveType == 0)
                {
                    squareDuty += dutySweep;
                    if(squareDuty < 0.0f)
                        squareDuty = 0.0f;
                    else if (squareDuty > 0.5f)
                        squareDuty = 0.5f;
                }

                // Moves through the different stages of the volume envelope
                if(++envelopeTime > envelopeLength)
                {
                    envelopeTime = 0;

                    switch(++envelopeStage)
                    {
                        case 1:
                            envelopeLength = envelopeLength1;
                            break;
                        case 2:
                            envelopeLength = envelopeLength2;
                            break;
                    }
                }

                // Sets the volume based on the position in the envelope
                switch(envelopeStage)
                {
                    case 0:
                        envelopeVolume = envelopeTime * envelopeOverLength0;
                        break;
                    case 1:
                        envelopeVolume = 1.0f + (1.0f - envelopeTime * envelopeOverLength1) * 2.0f * sustainPunch;
                        break;
                    case 2:
                        envelopeVolume = 1.0f - envelopeTime * envelopeOverLength2;
                        break;
                    case 3:
                        envelopeVolume = 0.0f;
                        finished = true;
                        break;
                }

                // Moves the phaser offset
                if (phaser)
                {
                    phaserOffset += phaserDeltaOffset;
                    phaserInt = (int)phaserOffset;
                    if(phaserInt < 0)
                        phaserInt = -phaserInt;
                    else if (phaserInt > 1023)
                        phaserInt = 1023;
                }

                // Moves the high-pass filter cutoff
                if(filters && hpFilterDeltaCutoff != 0.0)
                {
                    hpFilterCutoff *= hpFilterDeltaCutoff;
                    if(hpFilterCutoff < 0.00001f)
                        hpFilterCutoff = 0.00001f;
                    else if(hpFilterCutoff > 0.1f)
                        hpFilterCutoff = 0.1f;
                }

                superSample = 0.0f;
                for(int j = 0; j < 8; j++)
                {
                    // Cycles through the period
                    phase++;
                    if(phase >= periodTemp)
                    {
                        phase = phase - (int)periodTemp;

                        // Generates new random noise for this period
                        if(waveType == WaveType.Noise)
                        {
                            for(int n=0; n<32; n++)
                                noiseBuffer[n] = (float)random.NextDouble() * 2.0f - 1.0f;
                        }
                    }

                    // Gets the sample from the oscillator
                    switch(waveType)
                    {
                        case WaveType.Square: // Square wave
                        {
                            sample = ((phase / periodTemp) < squareDuty) ? 0.5f : -0.5f;
                            break;
                        }
                        case WaveType.Saw: // Saw wave
                        {
                            sample = 1.0f - (phase / periodTemp) * 2.0f;
                            break;
                        }
                        case WaveType.Sin: // Sine wave (fast and accurate approx)
                        {
                            pos = phase / periodTemp;
                            pos = pos > 0.5f ? (pos - 1.0f) * 6.28318531f : pos * 6.28318531f;
                            sample = pos < 0 ? 1.27323954f * pos + .405284735f * pos * pos : 1.27323954f * pos - 0.405284735f * pos * pos;
                            sample = sample < 0 ? .225f * (sample *-sample - sample) + sample : .225f * (sample * sample - sample) + sample;

                            break;
                        }
                        case WaveType.Noise: // Noise
                        {
                            sample = noiseBuffer[(phase * 32 / (int)periodTemp) % 32];
                            break;
                        }
                    }

                    // Applies the low and high pass filters
                    if (filters)
                    {
                        lpFilterOldPos = lpFilterPos;
                        lpFilterCutoff *= lpFilterDeltaCutoff;
                        if(lpFilterCutoff < 0.0f)
                            lpFilterCutoff = 0.0f;
                        else if(lpFilterCutoff > 0.1f)
                            lpFilterCutoff = 0.1f;

                        if(lpFilterOn)
                        {
                            lpFilterDeltaPos += (sample - lpFilterPos) * lpFilterCutoff;
                            lpFilterDeltaPos *= lpFilterDamping;
                        }
                        else
                        {
                            lpFilterPos = sample;
                            lpFilterDeltaPos = 0.0f;
                        }

                        lpFilterPos += lpFilterDeltaPos;

                        hpFilterPos += lpFilterPos - lpFilterOldPos;
                        hpFilterPos *= 1.0f - hpFilterCutoff;
                        sample = hpFilterPos;
                    }

                    // Applies the phaser effect
                    if (phaser)
                    {
                        phaserBuffer[phaserPos & 1023] = sample;
                        sample += phaserBuffer[(phaserPos - phaserInt + 1024) & 1023];
                        phaserPos = (phaserPos + 1) & 1023;
                    }

                    superSample += sample;
                }

                // Averages out the super samples and applies volumes
                superSample = masterVolume * envelopeVolume * superSample * 0.125f;

                // Clipping if too loud
                if(superSample > 1.0f)
                    superSample = 1.0f;
                else if(superSample < -1.0f)
                    superSample = -1.0f;

                samples[i] = (int)(32000.0 * superSample);

                samplesInBuffer++;
            }

            byte[] byteSamples = new byte[samplesInBuffer * 2];
            for (int i = 0; i < samplesInBuffer; i++)
            {
                if(BitConverter.IsLittleEndian)
                {
                    byteSamples[i * 2] = (byte)(samples[i] & 0xff);
                    byteSamples[i * 2 + 1] = (byte)(samples[i] >> 8);
                }
                else
                {
                    byteSamples[i * 2] = (byte)(samples[i] >> 8);
                    byteSamples[i * 2 + 1] = (byte)(samples[i] & 0xff);
                }
            }

            return new SoundEffect(byteSamples, 44100, AudioChannels.Mono);
        }
Exemple #6
0
 public SoundEffect CreateMutation(SfxrParams sfxrParams, double mutation)
 {
     return CreateSound(sfxrParams.GetMutation(mutation));
 }
Exemple #7
0
 public SfxrParams GetMutation(double mutation)
 {
     SfxrParams p = new SfxrParams(this);
     p.Mutate(mutation);
     return p;
 }
        public void CreateSound(SfxrParams sfxrParams, int bufferSize)
        {
            _synthesizedBlocks = new Queue<SynthesizedBuffer>();

            this.BufferSize = bufferSize;
            this.IsReadyToPlay = false;
            this.IsPlaying = false;

            _currentSynthesizedSample = 0;

            //TODO: check out where is the sample rate for the generation??
            localParams = new SfxrParams(sfxrParams);

            Reset(true);
            CacheSamples();
        }
 public void CreateMutation(SfxrParams sfxrParams, double mutation, int bufferSize)
 {
     CreateSound(sfxrParams.GetMutation(mutation), bufferSize);
 }
        private void Reset(bool totalReset)
        {
            SfxrParams p = localParams;

            period    = 100.0f / (p.StartFrequency * p.StartFrequency + 0.001f);
            maxPeriod = 100.0f / (p.MinFrequency * p.MinFrequency + 0.001f);

            slide      = 1.0f - p.Slide * p.Slide * p.Slide * 0.01f;
            deltaSlide = -p.DeltaSlide * p.DeltaSlide * p.DeltaSlide * 0.000001f;

            if (p.WaveType == WaveType.Square)
            {
                squareDuty = 0.5f - p.SquareDuty * 0.5f;
                dutySweep  = -p.DutySweep * 0.00005f;
            }

            if (p.ChangeAmount > 0.0f)
            {
                changeAmount = 1.0f - p.ChangeAmount * p.ChangeAmount * 0.9f;
            }
            else
            {
                changeAmount = 1.0f + p.ChangeAmount * p.ChangeAmount * 10.0f;
            }

            changeTime = 0;

            if (p.ChangeSpeed == 1.0)
            {
                changeLimit = 0;
            }
            else
            {
                changeLimit = (int)((1.0f - p.ChangeSpeed) * (1.0f - p.ChangeSpeed) * 20000 + 32);
            }

            if (totalReset)
            {
                masterVolume = p.MasterVolume * p.MasterVolume;

                waveType = p.WaveType;

                if (p.SustainTime < 0.01f)
                {
                    p.SustainTime = 0.01f;
                }

                double totalTime = p.AttackTime + p.SustainTime + p.DecayTime;
                if (totalTime < 0.18)
                {
                    double multiplier = 0.18 / totalTime;
                    p.AttackTime  *= multiplier;
                    p.SustainTime *= multiplier;
                    p.DecayTime   *= multiplier;
                }

                sustainPunch = p.SustainPunch;

                phase = 0;

                minFrequency = p.MinFrequency;

                filters = p.lpFilterCutoff != 1.0 || p.hpFilterCutoff != 0.0;

                lpFilterPos         = 0.0f;
                lpFilterDeltaPos    = 0.0f;
                lpFilterCutoff      = p.lpFilterCutoff * p.lpFilterCutoff * p.lpFilterCutoff * 0.1f;
                lpFilterDeltaCutoff = 1.0f + p.lpFilterCutoffSweep * 0.0001f;
                lpFilterDamping     = 5.0f / (1.0f + p.lpFilterResonance * p.lpFilterResonance * 20.0f) * (0.01f + lpFilterCutoff);
                if (lpFilterDamping > 0.8)
                {
                    lpFilterDamping = 0.8f;
                }
                lpFilterDamping = 1.0f - lpFilterDamping;
                lpFilterOn      = p.lpFilterCutoff != 1.0f;

                hpFilterPos         = 0.0f;
                hpFilterCutoff      = p.hpFilterCutoff * p.hpFilterCutoff * 0.1f;
                hpFilterDeltaCutoff = 1.0f + p.hpFilterCutoffSweep * 0.0003f;

                vibratoPhase     = 0.0f;
                vibratoSpeed     = p.VibratoSpeed * p.VibratoSpeed * 0.01f;
                vibratoAmplitude = p.VibratoDepth * 0.5f;

                envelopeVolume     = 0.0f;
                envelopeStage      = 0;
                envelopeTime       = 0;
                envelopeLength0    = p.AttackTime * p.AttackTime * 100000.0f;
                envelopeLength1    = p.SustainTime * p.SustainTime * 100000.0f;
                envelopeLength2    = p.DecayTime * p.DecayTime * 100000.0f + 10;
                envelopeLength     = envelopeLength0;
                envelopeFullLength = envelopeLength0 + envelopeLength1 + envelopeLength2;

                envelopeOverLength0 = 1.0f / envelopeLength0;
                envelopeOverLength1 = 1.0f / envelopeLength1;
                envelopeOverLength2 = 1.0f / envelopeLength2;

                phaser = p.PhaserOffset != 0.0f || p.PhaserSweep != 0.0f;

                phaserOffset = p.PhaserOffset * p.PhaserOffset * 1020.0f;
                if (p.PhaserOffset < 0.0)
                {
                    phaserOffset = -phaserOffset;
                }
                phaserDeltaOffset = p.PhaserSweep * p.PhaserSweep * p.PhaserSweep * 0.2f;
                phaserPos         = 0;

                for (int i = 0; i < 1024; i++)
                {
                    phaserBuffer[i] = 0;
                }

                for (int i = 0; i < 32; i++)
                {
                    noiseBuffer[i] = (float)random.NextDouble() * 2.0f - 1.0f;
                }

                repeatTime = 0;

                if (p.RepeatSpeed == 0.0)
                {
                    repeatLimit = 0;
                }
                else
                {
                    repeatLimit = (int)((1.0f - p.RepeatSpeed) * (1.0f - p.RepeatSpeed) * 20000) + 32;
                }
            }
        }
 public void CreateMutation(SfxrParams sfxrParams, double mutation, int bufferSize)
 {
     CreateSound(sfxrParams.GetMutation(mutation), bufferSize);
 }