gain() public static method

public static gain ( double dB ) : double
dB double
return double
Ejemplo n.º 1
0
        public double Normalize(double dBfs, bool doIt)
        {
            // Make sure the whole buffer is scaled
            double gain = 0;
            double max  = 0;

            for (int j = 0; j < _samples.Count; j++)
            {
                ISample s = _samples[j];
                for (int c = 0; c < s.NumChannels; c++)
                {
                    max = Math.Max(max, Math.Abs(s[c]));
                }
            }
            if (max == 0)
            {
                return(0);
            }
            gain = MathUtil.gain(dBfs) / max;
            if (doIt)
            {
                ApplyGain(gain);
            }
            return(gain);
        }
Ejemplo n.º 2
0
        double mag(double f)
        {
            double ff = f - _startFreq;

            if (ff <= 0)
            {
                return((Math.Cos(Math.PI * ff / _startFreq) + 1) / 2);
            }
            double dbNow   = 1 - (10 * Math.Log10(f / _startFreq));
            double gainNow = MathUtil.gain(dbNow);

            return(gainNow);
        }
Ejemplo n.º 3
0
        private static double WeightedVolume2(SoundBuffer src, double dbSPL, double dbSPLBase)
        {
            double v  = 0;
            uint   sr = src.SampleRate;

            // Read buffer into array of complex
            Complex[][] data = src.ToComplexArray();

            // We only have a single channel
            Complex[] cdata = data[0];

            // FFT in place
            Fourier.FFT(cdata.Length, cdata);

            // Calculate magnitude, weighted by 80-phon loudness, for each loudness band.
            // These are the ISO measured points:
            FilterProfile lfg;

            if (dbSPLBase == 0)
            {
                lfg = SPL(dbSPL);
            }
            else
            {
                lfg = DifferentialSPL(dbSPL, dbSPLBase);
            }
//          lfg.Add(new FreqGain(sr / 2, lfg[lfg.Count - 1].Gain));

            // Cover the ISO measured range (only...)
            int nStart = (int)(lfg[0].Freq * (long)cdata.Length / sr);
            int nEnd   = (int)(lfg[lfg.Count - 1].Freq * (long)cdata.Length / sr);

            // Just use linear interpolation (on a dB scale; linear freq scale) of gain between each measured point
            int nfg = 0;

            int    startp = nStart;
            int    endp   = (int)(lfg[nfg + 1].Freq * (long)cdata.Length / sr); // endpoint of this band
            double dB1    = lfg[nfg].Gain;                                      // SPL of the ISO223 curve at this freq
            double dB2    = lfg[nfg + 1].Gain;                                  // ...and the next point

            double vThisBand = 0;
            int    nThisBand = 0;

            for (int j = nStart; j < nEnd; j++)
            {
                if (j > endp)
                {
                    if (nThisBand > 0)
                    {
                        v += Math.Sqrt(vThisBand / nThisBand);                // RMS
                    }
                    while (j >= endp)
                    {
                        nfg++;
                        startp = j;
                        endp   = (int)(lfg[nfg + 1].Freq * (long)cdata.Length / sr);
                        dB1    = lfg[nfg].Gain;
                        dB2    = lfg[nfg + 1].Gain;
                    }
                    vThisBand = 0;
                    nThisBand = 0;
                }
                Complex c      = cdata[j];
                double  dbHere = dB1 + ((dB2 - dB1) * (double)(j - startp) / (double)(endp - startp));
                vThisBand += (c.Re * c.Re) / MathUtil.gain(dbHere);
                nThisBand++;
            }
            if (nThisBand > 0)
            {
                v += Math.Sqrt(vThisBand / nThisBand);
            }

            return(v);
        }
Ejemplo n.º 4
0
 public LinearEnvelope(double dBstartGain, double dBendGain, int nSamples)
 {
     _startGain = MathUtil.gain(dBstartGain);
     _endGain   = MathUtil.gain(dBendGain);
     _nSamples  = nSamples;
 }
Ejemplo n.º 5
0
        private static IEnumerator <double> Arbitrary(int length, FilterProfile coeffs, uint sampleRate)
        {
            // Generate random-phase with specified magnitudes in the frequency domain, then IFFT.
            // This noise is periodic - length (next power of 2 from 'n')

            int l = MathUtil.NextPowerOfTwo(length);

            Complex[] data = new Complex[l];

            int    n     = 0;
            double freq1 = coeffs[n].Freq * 2 * l / sampleRate;
            double freq2 = coeffs[n + 1].Freq * 2 * l / sampleRate;
            double gain1 = coeffs[n].Gain;
            double gain2 = coeffs[n + 1].Gain;

            double logn = Math.Log(l);

            for (int j = 0; j < l; j++)
            {
                double gainDb;
                double gain;
                if (j > freq2)
                {
                    // Move to the next coefficient
                    n++;
                    if (n < coeffs.Count - 1)
                    {
                        freq1 = coeffs[n].Freq * 2 * l / sampleRate;
                        freq2 = coeffs[n + 1].Freq * 2 * l / sampleRate;
                        gain1 = coeffs[n].Gain;
                        gain2 = coeffs[n + 1].Gain;
                    }
                }
                if (j < freq1)
                {
                    gainDb = gain1;
                }
                else if (j > freq2)
                {
                    gainDb = gain2;
                }
                else
                {
                    // Raised Cosine: 0.5* ( cos(phi) + 1 ), from phi=pi to 2pi
                    //
                    double frac = (double)(j - freq1) / (double)(freq2 - freq1);
                    double ph   = Math.PI * (1 + frac);
                    double rcos = (1 + Math.Cos(ph)) / 2;
                    gainDb = gain1 + rcos * (gain2 - gain1);
                }
                gain = MathUtil.gain(gainDb);

                // Create a random phase value from 0 to 2pi
                double phi = NextRandom() * 2 * Math.PI;
                // Magnitude is 1, so just trig
                double re = Math.Cos(phi);
                double im = Math.Sin(phi);
                data[j] = new Complex(gain * logn * re, gain * logn * im);
            }

            // IFFT
            Fourier.IFFT((int)l, data);

            // Return the real component
            int k = 0;

            while (true)
            {
                yield return(data[k].Re * logn);

                k++;
                if (k >= l)
                {
                    k = 0;
                }
            }
        }
Ejemplo n.º 6
0
        ISoundObj CalculateSweep()
        {
            // Per http://www.anselmgoertz.de/Page10383/Monkey_Forest_dt/Manual_dt/aes-swp-english.pdf
            int fftSize = MathUtil.NextPowerOfTwo(_lengthSamples * 2);
            int N       = fftSize / 2;

            // Center the sweep in time to reduce impact of its extremities
            double fNyq   = _sr / 2;
            double FStart = _startFreq;
            double FEnd   = _endFreq;
            double SStart = (N - _lengthSamples) / 2;
            double TStart = SStart / _sr;
            double TEnd   = TStart + _lengthSecs;

            _B = (TEnd - TStart) / Math.Log(FEnd / FStart);
            _A = TStart - _B * Math.Log(FStart);

            // Make the complex spectrum
            //double ph = 0;
            double df     = (double)_sr / N;
            double phiNyq = phi(fNyq);
            double phiAdj = phiNyq % (2 * Math.PI);

            if (!_gotdata)
            {
                _data = new Complex[fftSize];
                fixed(Complex *cdata = _data)
                {
                    for (int j = 0; j < N; j++)
                    {
                        int    m  = j + 1;
                        double f  = (double)m * _sr / fftSize;
                        double ph = phi(f) - (f / fNyq) * phiAdj;
                        double v  = mag(f);
                        double Re = Math.Cos(ph) * v;
                        double Im = Math.Sin(ph) * v;
                        _data[j] = new Complex(Re, Im);
                    }
                    Fourier.IFFT(fftSize, _data, Math.Sqrt(fftSize) * _gain * MathUtil.gain(20));
                }

                // Look for values beyond the end
                // whose magnitude greater than our allowed threshold;
                // if present, window then ifft then start again.

                // Below doesn't seem to converge well
                // so just window and be done

                /*
                 * double threshold = MathUtil.gain(-90);
                 * bool iterate = true;
                 * while (iterate)
                 * {
                 *  iterate = false;
                 *  for (n = (int)(TEnd * sr + SStart * 2); n < fftSize; n++)
                 *  {
                 *      if (_data[n].Magnitude > threshold)
                 *      {
                 *          iterate = true;
                 *          break;
                 *      }
                 *  }
                 *  if (iterate)
                 *  {
                 *      Blackman bh = new Blackman((int)(_lengthSamples / 2 + SStart), _lengthSamples / 200, _lengthSamples / 2);
                 *      bh.Input = cbr;
                 *      n=0;
                 *      foreach (ISample s in bh)
                 *      {
                 *          _data[n++] = new Complex(s[0],0);
                 *      }
                 *      Fourier.FFT(fftSize, _data);
                 *      for (n = 0; n < N; n++)
                 *      {
                 *          int m = n + 1;
                 *          double f = (double)m * sr / fftSize;
                 *          double ph = _data[n].Phase;
                 *          double v = mag(f);
                 *          double Re = Math.Cos(ph) * v;
                 *          double Im = Math.Sin(ph) * v;
                 *          _data[n] = new Complex(Re, Im);
                 *      }
                 *      Fourier.IFFT(fftSize, _data);
                 *  }
                 * }
                 */

                CosWindow            bh    = new Hamming((int)(_lengthSamples / 2 + SStart), (int)(SStart), _lengthSamples / 2);
                IEnumerator <double> gains = bh.Gains;
                for (int j = 0; j < N; j++)
                {
                    gains.MoveNext();
                    double g = gains.Current;
                    _data[j].mul(g);
                    _data[fftSize - j - 1].mul(g);
                }

                _gotdata = true;
            }

            ComplexBufferReader cbr = new ComplexBufferReader(_data, 0, N);

            //bh.Input = cbr;

            return(cbr);
        }