Ejemplo n.º 1
0
    public float frequencyModulationRangeOut;       //The Frequency Modulation Oscillator’s current value (range 0 to 1)



    void Awake()
    {
        amplitudeModulationOscillator = new SineHP();
        frequencyModulationOscillator = new SineHP();

        // Grab the sample rate from the system
        _FS = AudioSettings.outputSampleRate;
        // Calculate how long each sample lasts
        _sampleDuration = 1.0 / _FS;
    }
Ejemplo n.º 2
0
    void OnAudioFilterRead(float[] data, int channels)
    {
        /*
         * This is "the current time of the audio system", as given
         * by Unity. It is updated every time the OnAudioFilterRead() function
         * is called. It's usually every 1024 samples.
         *
         * A note on the sample rate:
         * We don't actually see real numbers for the sample rate, we instead
         * read it from the system in the Start() function.
         */

        //currentDspTime = AudioSettings.dspTime;

        // goes through data chunk
        for (int i = 0; i < data.Length; i += channels)
        {
            /*
             * Sample duration is just 1/fs. Because dspTime isn't updated every
             * sample, we "update" it ourselves so our envelope sounds smooth.
             */
            //  currentDspTime += _sampleDuration;
            //  envelope = ComputeAmplitude(currentDspTime) * volume;

            // lets you modulate the frequency
            double currentFreq = frequency;



            // Applies Frequency Modulation
            if (useFrequencyModulation)
            {
                phaseIncrementFM = (frequencyModulationOscillatorFrequency) * 2.0 * Mathf.PI / _FS;
                phaseFM         += phaseIncrementFM;
                if (phaseFM > (Mathf.PI * 2))
                {
                    phaseFM = phaseFM % (Mathf.PI * 2);
                }

                double freqOffset = (frequencyModulationOscillatorIntensity * frequency * 0.75) / 100.0;
                currentFreq += mapValueD(SineHP.Sin((float)phaseFM), -1.0, 1.0, -freqOffset, freqOffset);
                frequencyModulationRangeOut = (float)SineHP.Sin((float)phaseFM) * 0.5f + 0.5f;
            }
            else
            {
                frequencyModulationRangeOut = 0.0f;
            }


            /*
             * The phase variable below increments by the calculated amount for
             * every audio sample. We can then use this value to calculate what
             * each waveform's value should be.
             *
             *             2pi * f
             *     phase = -------
             *               fs
             *
             * When phase is greater than 2pi, we just reset
             * it so we don't have an ever-increasing variable that will cause
             * an overflow error.
             */

            phaseIncrement = (currentFreq * octave) * 2.0 * Mathf.PI / _FS;
            phase         += phaseIncrement;
            if (phase > (Mathf.PI * 2))
            {
                phase = phase % (Mathf.PI * 2);
            }

            nextOutput  = 0;
            sinOutput   = 0;
            sawOutput   = 0;
            sqrOutput   = 0;
            noiseOutput = 0;

            // Adds sinusoidal wave to the next output sample                   sinOutput = (float)(sinWeight * Mathf.Sin((float)phase));
            sinOutput = (float)(sinWeight * SineHP.Sin((float)phase));
            // nextOutput += (float)(sinWeight * Mathf.Sin((float)phase));

            // Adds sawtooth wave to the next output sample
            sawOutput = (float)sawWeight - (float)(sawWeight / Mathf.PI * phase);

            // nextOutput += (float)(sawWeight * ((phase) / (2 * Mathf.PI)));



            // Adds square wave to the next output sample
            if (phase > Mathf.PI)
            {
                sqrOutput = (float)(sqrWeight);
                //nextOutput += (float) (sqrWeight ) ;
            }
            else
            {
                sqrOutput = (-(float)(sqrWeight));
                //nextOutput += (-(float) ( sqrWeight) ) ;
            }


            // Adds noise wave to the next output sample
            noiseOutput = PinkNoise.Noise();


            /*      Mixa tutti gli output
             *     http://www.vttoth.com/CMS/index.php/technical-notes/68
             * Let's say we have two signals, A and B. If A is quiet, we want to hear B on the output in unaltered form. If B
             * is quiet, we want to hear A on the output (i.e., A and B are treated symmetrically.) If both A and B have a non-zero amplitude,
             * the mixed signal must have an amplitude between the greater of A and B, and the maximum permissible amplitude.
             * If we take A and B to have values between 0 and 1, there is actually a simple equation that satisfies all of the
             * above conditions:       Z= A + B − AB.
             * Simple, isn't it! Moreover, it can be easily adapted for more than two signals.
             * Consider what happens if we mix another signal, C, to Z:  T= Z + C − Z C = A + B + C − AB − AC − BC + ABC.
             *
             *
             */
            nextOutput = sinOutput + sawOutput + sqrOutput - (sinOutput * sawOutput) -
                         (sinOutput * sqrOutput) - (sawOutput * sqrOutput) + (sinOutput * sawOutput * sqrOutput);

            nextOutput += noiseOutput * (float)noiseWeight;      //da cambiare

            /*
             * Here we apply a single-pole low-pass filter. Even if the filter
             * is completely open (lowPass = 1) we still compute this step so we
             * don't have to have any conditional logic.
             */
            nextOutput = (float)((nextOutput * lowPass) + (previousOutput * (1 - lowPass)));

            nextOutput = nextOutput * 0.5f * volume;



            // Applies Amplitude Modulation
            if (useAmplitudeModulation)
            {
                phaseIncrementAM = (amplitudeModulationOscillatorFrequency) * 2.0 * Mathf.PI / _FS;
                phaseAM         += phaseIncrementAM;
                if (phaseAM > (Mathf.PI * 2))
                {
                    phaseAM = phaseAM % (Mathf.PI * 2);
                }
                nextOutput *= (float)mapValueD(SineHP.Sin((float)phaseAM), -1.0, 1.0, 0.0, 1.0);
                amplitudeModulationRangeOut = (float)SineHP.Sin((float)phaseAM) * 0.5f + 0.5f;
            }
            else
            {
                amplitudeModulationRangeOut = 0.0f;
            }



            // Write the output to the audio filter
            data[i] += nextOutput;

            // This is for the next low-pass calculation
            previousOutput = nextOutput;

            // Copy the sound from one channel into the next channel for stereo
            if (channels == 2)
            {
                data[i + 1] = data[i];
            }
        }
    }