/// <summary> /// Multiply the profile by the given gain factor. /// </summary> /// <param name="scale"></param> /// <returns></returns> public FilterProfile Scale(double scale) { FilterProfile lfg = new FilterProfile(); for (int j = 0; j < lfg.Count; j++) { FreqGain fg = lfg[j]; lfg.Add(new FreqGain(fg.Freq, fg.Gain * scale)); } return(lfg); }
/// <summary> /// Create a subset of the profile, within the given frequency range. /// </summary> /// <param name="fMin"></param> /// <param name="fMax"></param> /// <returns></returns> public FilterProfile FreqRange(double fMin, double fMax) { FilterProfile lfg = new FilterProfile(); foreach (FreqGain fg in this) { if (fg.Freq >= fMin && fg.Freq <= fMax) { lfg.Add(fg); } } return(lfg); }
public static FilterProfile DifferentialSPL(double phon0, double phon1, double scale) { FilterProfile spl = new FilterProfile(); FilterProfile spl0 = Loudness.SPL(phon0); FilterProfile spl1 = Loudness.SPL(phon1); for (int j = 0; j < spl1.Count; j++) { FreqGain fg = spl1[j]; fg.Gain = scale * (spl0[j].Gain - fg.Gain); spl.Add(fg); } return(spl); }
/// <summary> /// Return a list of freq/gain, at the ERB centers /// Assuming you smoothed the data... /// </summary> /// <param name="data">data from ERB.smooth</param> /// <param name="sr">sample rate</param> /// <param name="scaleFactor">1.0 for ~38 bands. 0.5 for twice as many...</param> /// <returns></returns> public static FilterProfile profile(double[] data, uint sr, double scaleFactor) { FilterProfile pts = new FilterProfile(); int dl = data.Length; for (double j = 1; j < ERB.ERBVal(sr / 2) + 1; j += scaleFactor) { double f = ERB.invERBVal(j); double n = f * 2 * dl / sr; if (n < dl) { double g = data[(int)n]; pts.Add(new FreqGain(f, g)); } } return(pts); }
public FilterProfile Inverse(double maxGain) { FilterProfile lfg = new FilterProfile(); foreach (FreqGain fg in this) { double newGain = -fg.Gain; if (maxGain != 0) { // Don't make more than +/-maxGain dB difference! newGain = Math.Min(newGain, maxGain); newGain = Math.Max(newGain, -maxGain); lfg.Add(new FreqGain(fg.Freq, newGain)); } } return(lfg); }
/// <summary> /// Create a linear-phase filter impulse. /// </summary> /// <param name="nSize">Size: determines length of the final filter - suggest 4096 or 8192 (or 0 to auto-set)</param> /// <param name="coefficients">List of {frequency Hz, gain dB}</param> /// <param name="interpolation">type of interpolation (cosine)</param> public FilterImpulse(int nSize, FilterProfile coefficients, FilterInterpolation interpolation, uint sampleRate) { if (sampleRate == 0) { throw new Exception("Sample rate cannot be zero"); } _nSamples = nSize; _coeffs = coefficients; _int = interpolation; SampleRate = sampleRate; // Check the coefficients are sorted and non-overlapping _coeffs.Sort(new FreqGainComparer()); FilterProfile co = new FilterProfile(); _allZero = true; double prevFreq = -1; double freqDiff = double.MaxValue; foreach (FreqGain fg in _coeffs) { if (fg.Freq > prevFreq && fg.Freq >= 0) { co.Add(fg); freqDiff = Math.Min(freqDiff, fg.Freq - prevFreq); prevFreq = fg.Freq; } if (fg.Gain != 0) { _allZero = false; } } _coeffs = co; if (_nSamples == 0) { // Make up a length from 4k to 32k, based on the closest-together frequencies _nSamples = _allZero ? 1024 : Math.Max(4096, (int)Math.Min(32768.0, 327680 / freqDiff)); } _nSamples = MathUtil.NextPowerOfTwo(_nSamples); }
/// <summary> /// Subtract one profile from another. /// Only valid if they share the same frequency set. /// </summary> /// <param name="c1"></param> /// <param name="c2"></param> /// <returns></returns> public static FilterProfile operator -(FilterProfile c1, FilterProfile c2) { if (c1.Count != c2.Count) { return(null); } FilterProfile newProfile = new FilterProfile(); for (int j = 0; j < c1.Count; j++) { if (c1[j].Freq != c2[j].Freq) { return(null); } double g1 = c1[j].Gain; double g2 = c2[j].Gain; newProfile.Add(new FreqGain(c1[j].Freq, g1 - g2)); } return(newProfile); }
/// <summary> /// Create a list of dB SPL equal-loudness values for a given 'phon' loudness /// (from zero, threshold, to 90) /// </summary> /// <param name="phon"></param> /// <returns>list of {frequency Hz, dB SPL}</returns> public static FilterProfile SPL(double phon) { FilterProfile lfg = new FilterProfile(); if ((phon < 0) | (phon > 120)) { throw new ArgumentException("Phon value out of bounds!"); } // Setup user-defined values for equation double Ln = phon; for (int j = 0; j < f.Length; j++) { // Deriving sound pressure level from loudness level (iso226 sect 4.1) double Af = 4.47E-3 * Math.Pow(10, (0.025 * Ln) - 1.15) + Math.Pow(0.4 * Math.Pow(10, (((Tf[j] + Lu[j]) / 10) - 9)), af[j]); double Lp = ((10 / af[j]) * Math.Log10(Af)) - Lu[j] + 94; // Return user data FreqGain fg = new FreqGain(f[j], Lp); lfg.Add(fg); } return(lfg); }
/// <summary> /// Return a list of freq/gain, only including inflection points (where the curve is flat). /// </summary> /// <param name="data"></param> /// <param name="sr"></param> /// <returns></returns> public static FilterProfile inflections(double[] data, uint sr) { // Differentiate double bins = data.Length + 1; double[] diff = new double[data.Length]; double n = data[0]; for (int j = 0; j < data.Length; j++) { double d = data[j]; diff[j] = d - n; n = d; } // Look for zero-crossings of the first derivative of data[] // (always include [0] and [end]) FilterProfile pts = new FilterProfile(); int bin; double pt = 0.1; int last = -1; double freq; double lastfreq = -1; // Always start with points for zero and 10 Hz pts.Add(new FreqGain(0, MathUtil.dB(data[0]))); freq = 10; bin = (int)f2bin(freq, sr, bins); pts.Add(new FreqGain(freq, MathUtil.dB(data[bin]))); pt = diff[bin]; for (int j = bin + 1; j < data.Length; j++) { if ((pt > 0 && diff[j] <= 0) || (pt < 0 && diff[j] >= 0)) { freq = bin2f(j, sr, bins); pts.Add(new FreqGain(freq, MathUtil.dB(data[j]))); last = j; lastfreq = freq; } pt = diff[j]; } // Fill in the last few target samples if (lastfreq < (sr / 2) - 2050) { freq = (sr / 2) - 2050; bin = (int)f2bin(freq, sr, bins); pts.Add(new FreqGain(freq, MathUtil.dB(data[bin]))); } if (lastfreq < (sr / 2) - 1550) { freq = (sr / 2) - 1550; bin = (int)f2bin(freq, sr, bins); pts.Add(new FreqGain(freq, MathUtil.dB(data[bin]))); } if (lastfreq < sr / 2) { freq = sr / 2; pts.Add(new FreqGain(freq, MathUtil.dB(data[data.Length - 1]))); } return(pts); }
public static FilterProfile diffuseDiff15() { // from Farina data -15 degrees FilterProfile lfg = new FilterProfile(); lfg.Add(new FreqGain(29.8999517172724, -0.0863917163326701)); lfg.Add(new FreqGain(45.9318520170928, -0.086646594026467)); lfg.Add(new FreqGain(62.7349359370437, -0.0874548658683244)); lfg.Add(new FreqGain(80.348144199439, -0.0879751392064135)); lfg.Add(new FreqGain(98.812561979239, -0.0890868621043947)); lfg.Add(new FreqGain(118.171554124747, -0.0902608074810529)); lfg.Add(new FreqGain(138.470910523652, -0.0909038889250574)); lfg.Add(new FreqGain(159.759002525445, -0.0923344140142375)); lfg.Add(new FreqGain(182.086951427111, -0.0937822151583515)); lfg.Add(new FreqGain(205.508810136376, -0.0951728613131329)); lfg.Add(new FreqGain(230.081759247243, -0.0964831892699499)); lfg.Add(new FreqGain(255.866318897917, -0.0977855409466679)); lfg.Add(new FreqGain(282.926577933456, -0.0996764404835705)); lfg.Add(new FreqGain(311.330442067148, -0.100486603558354)); lfg.Add(new FreqGain(341.14990292827, -0.100051270274286)); lfg.Add(new FreqGain(372.461330102897, -0.0979260196990259)); lfg.Add(new FreqGain(405.345788522409, -0.0908775515206414)); lfg.Add(new FreqGain(439.889383835671, -0.0782636965770721)); lfg.Add(new FreqGain(476.183638720577, -0.0589294155247667)); lfg.Add(new FreqGain(514.325903454604, -0.0331101724182802)); lfg.Add(new FreqGain(554.419804479247, 0.0100958113611724)); lfg.Add(new FreqGain(596.575735167586, 0.0479470506982144)); lfg.Add(new FreqGain(640.911393547776, 0.105430778442781)); lfg.Add(new FreqGain(687.552372358488, 0.168896217319817)); lfg.Add(new FreqGain(736.632807529586, 0.237255771124081)); lfg.Add(new FreqGain(788.296092007413, 0.328490953798301)); lfg.Add(new FreqGain(842.695662798627, 0.402734259074768)); lfg.Add(new FreqGain(899.99587021156, 0.494326782264423)); lfg.Add(new FreqGain(960.372939556513, 0.578128079437876)); lfg.Add(new FreqGain(1024.01603705869, 0.660125601312093)); lfg.Add(new FreqGain(1091.12845347812, 0.712681005041455)); lfg.Add(new FreqGain(1161.92892096669, 0.732542794364541)); lfg.Add(new FreqGain(1236.65308108085, 0.726404101177543)); lfg.Add(new FreqGain(1315.55512467678, 0.698273367243763)); lfg.Add(new FreqGain(1398.90962772937, 0.645682099120009)); lfg.Add(new FreqGain(1487.01361103779, 0.571255784106514)); lfg.Add(new FreqGain(1580.18885643692, 0.4830388210465)); lfg.Add(new FreqGain(1678.7845176806, 0.408070371811873)); lfg.Add(new FreqGain(1783.18007079301, 0.35550515378515)); lfg.Add(new FreqGain(1893.78865663959, 0.319200925184918)); lfg.Add(new FreqGain(2011.06087804797, 0.311247539991447)); lfg.Add(new FreqGain(2135.48912539139, 0.320676353553954)); lfg.Add(new FreqGain(2267.61251860637, 0.337219551748223)); lfg.Add(new FreqGain(2408.02257075748, 0.396218572472187)); lfg.Add(new FreqGain(2557.3696992537, 0.477239191635716)); lfg.Add(new FreqGain(2716.3707366486, 0.49349820475482)); lfg.Add(new FreqGain(2885.81762489105, 0.454308524133459)); lfg.Add(new FreqGain(3066.58751658265, 0.202619261440745)); lfg.Add(new FreqGain(3259.65455639083, -0.229775101327912)); lfg.Add(new FreqGain(3466.1036780904, -0.679735290459132)); lfg.Add(new FreqGain(3687.14683149463, -1.14273604455762)); lfg.Add(new FreqGain(3924.14215377249, -1.58712231737431)); lfg.Add(new FreqGain(4178.61672801844, -2.24464955682634)); lfg.Add(new FreqGain(4452.29373750316, -2.95221883480249)); lfg.Add(new FreqGain(4747.12503915768, -3.59713042788595)); lfg.Add(new FreqGain(5065.3304615832, -3.95400511725521)); lfg.Add(new FreqGain(5409.44550497149, -4.26734231473008)); lfg.Add(new FreqGain(5782.37961614996, -4.29752236704959)); lfg.Add(new FreqGain(6187.48787900699, -3.80417940781499)); lfg.Add(new FreqGain(6628.65986711531, -3.42269750300152)); lfg.Add(new FreqGain(7110.43065099071, -2.67952601614751)); lfg.Add(new FreqGain(7638.12068410502, -1.40074317089712)); lfg.Add(new FreqGain(8218.013729816, -0.278815569277744)); lfg.Add(new FreqGain(8857.58547111898, -0.10133776498712)); lfg.Add(new FreqGain(9565.80048575836, -1.16608058344807)); lfg.Add(new FreqGain(10353.5026895216, -1.11758243515913)); lfg.Add(new FreqGain(11233.9354678215, 0.278943448347119)); lfg.Add(new FreqGain(12223.4446965003, 0.908362838092288)); lfg.Add(new FreqGain(13342.444347283, 0.57561474694365)); lfg.Add(new FreqGain(14616.7666969568, -0.0622868258733881)); lfg.Add(new FreqGain(16079.5885672628, -0.254955438747692)); lfg.Add(new FreqGain(17774.2422466263, -0.24984582194041)); lfg.Add(new FreqGain(19758.4244207167, -0.00233095236861375)); lfg.Add(new FreqGain(22110.6876081231, -0.000536752738788648)); return(lfg); }
public static FilterProfile diffuseDiff0() { // from Farina data 0 degrees FilterProfile lfg = new FilterProfile(); lfg.Add(new FreqGain(29.8999517172724, -0.819594013962942)); lfg.Add(new FreqGain(45.9318520170928, -0.825206846036483)); lfg.Add(new FreqGain(62.7349359370437, -0.843228404280093)); lfg.Add(new FreqGain(80.348144199439, -0.85549279781466)); lfg.Add(new FreqGain(98.812561979239, -0.885552104079416)); lfg.Add(new FreqGain(118.171554124747, -0.921814975716754)); lfg.Add(new FreqGain(138.470910523652, -0.941989434053033)); lfg.Add(new FreqGain(159.759002525445, -0.986288515963084)); lfg.Add(new FreqGain(182.086951427111, -1.03487811152306)); lfg.Add(new FreqGain(205.508810136376, -1.08724309366587)); lfg.Add(new FreqGain(230.081759247243, -1.14301616694228)); lfg.Add(new FreqGain(255.866318897917, -1.20202072457563)); lfg.Add(new FreqGain(282.926577933456, -1.29716987120868)); lfg.Add(new FreqGain(311.330442067148, -1.36375538636994)); lfg.Add(new FreqGain(341.14990292827, -1.4644642435199)); lfg.Add(new FreqGain(372.461330102897, -1.52904718749126)); lfg.Add(new FreqGain(405.345788522409, -1.61553093677067)); lfg.Add(new FreqGain(439.889383835671, -1.68163798221837)); lfg.Add(new FreqGain(476.183638720577, -1.71733965267451)); lfg.Add(new FreqGain(514.325903454604, -1.71900339686128)); lfg.Add(new FreqGain(554.419804479247, -1.66747850462173)); lfg.Add(new FreqGain(596.575735167586, -1.59447747686689)); lfg.Add(new FreqGain(640.911393547776, -1.45582456727674)); lfg.Add(new FreqGain(687.552372358488, -1.28169168214036)); lfg.Add(new FreqGain(736.632807529586, -1.08266101402942)); lfg.Add(new FreqGain(788.296092007413, -0.799257236450344)); lfg.Add(new FreqGain(842.695662798627, -0.550308170104235)); lfg.Add(new FreqGain(899.99587021156, -0.216876477890536)); lfg.Add(new FreqGain(960.372939556513, 0.123762097833653)); lfg.Add(new FreqGain(1024.01603705869, 0.504501005258036)); lfg.Add(new FreqGain(1091.12845347812, 0.806009630861022)); lfg.Add(new FreqGain(1161.92892096669, 0.970563802808751)); lfg.Add(new FreqGain(1236.65308108085, 0.993384317252108)); lfg.Add(new FreqGain(1315.55512467678, 0.899269754624433)); lfg.Add(new FreqGain(1398.90962772937, 0.71574567174392)); lfg.Add(new FreqGain(1487.01361103779, 0.42413561491627)); lfg.Add(new FreqGain(1580.18885643692, 0.0143087139306365)); lfg.Add(new FreqGain(1678.7845176806, -0.374163000274005)); lfg.Add(new FreqGain(1783.18007079301, -0.604206586990272)); lfg.Add(new FreqGain(1893.78865663959, -0.643361845768994)); lfg.Add(new FreqGain(2011.06087804797, -0.450261422187758)); lfg.Add(new FreqGain(2135.48912539139, -0.117143308385737)); lfg.Add(new FreqGain(2267.61251860637, 0.0726448007728625)); lfg.Add(new FreqGain(2408.02257075748, 0.149673576192565)); lfg.Add(new FreqGain(2557.3696992537, -0.0705597943707172)); lfg.Add(new FreqGain(2716.3707366486, -0.615399531580617)); lfg.Add(new FreqGain(2885.81762489105, -0.715844747528019)); lfg.Add(new FreqGain(3066.58751658265, -0.80980936924732)); lfg.Add(new FreqGain(3259.65455639083, -0.724599496650513)); lfg.Add(new FreqGain(3466.1036780904, -1.74219819410634)); lfg.Add(new FreqGain(3687.14683149463, -3.60307539107681)); lfg.Add(new FreqGain(3924.14215377249, -5.62149036113584)); lfg.Add(new FreqGain(4178.61672801844, -7.30684974206415)); lfg.Add(new FreqGain(4452.29373750316, -9.58452126557679)); lfg.Add(new FreqGain(4747.12503915768, -12.7988548069547)); lfg.Add(new FreqGain(5065.3304615832, -14.2817841410128)); lfg.Add(new FreqGain(5409.44550497149, -14.3089505650728)); lfg.Add(new FreqGain(5782.37961614996, -14.7676142885599)); lfg.Add(new FreqGain(6187.48787900699, -15.4620314368829)); lfg.Add(new FreqGain(6628.65986711531, -17.5471846623073)); lfg.Add(new FreqGain(7110.43065099071, -16.7838733846363)); lfg.Add(new FreqGain(7638.12068410502, -11.2810169858127)); lfg.Add(new FreqGain(8218.013729816, -6.43017437119144)); lfg.Add(new FreqGain(8857.58547111898, -2.58756224649037)); lfg.Add(new FreqGain(9565.80048575836, -3.18112947019392)); lfg.Add(new FreqGain(10353.5026895216, -5.40667046909438)); lfg.Add(new FreqGain(11233.9354678215, -3.35732869042161)); lfg.Add(new FreqGain(12223.4446965003, -1.40180859827503)); lfg.Add(new FreqGain(13342.444347283, -2.18457352314182)); lfg.Add(new FreqGain(14616.7666969568, -2.52559711716481)); lfg.Add(new FreqGain(16079.5885672628, -2.64456253082918)); lfg.Add(new FreqGain(17774.2422466263, -2.07661523855391)); lfg.Add(new FreqGain(19758.4244207167, -0.0243216938532986)); lfg.Add(new FreqGain(22110.6876081231, -0.00493030880131535)); return(lfg); }
public static FilterProfile diffuseDiff45() { // from Farina data -45 degrees FilterProfile lfg = new FilterProfile(); lfg.Add(new FreqGain(29.8999517172724, 0.034493028904745)); lfg.Add(new FreqGain(45.9318520170928, 0.0348965563859305)); lfg.Add(new FreqGain(62.7349359370437, 0.0361962782805971)); lfg.Add(new FreqGain(80.348144199439, 0.0370951759531601)); lfg.Add(new FreqGain(98.812561979239, 0.0393802905089846)); lfg.Add(new FreqGain(118.171554124747, 0.0422391555889454)); lfg.Add(new FreqGain(138.470910523652, 0.0438547095733166)); lfg.Add(new FreqGain(159.759002525445, 0.0474495412837798)); lfg.Add(new FreqGain(182.086951427111, 0.0515476348543647)); lfg.Add(new FreqGain(205.508810136376, 0.056162673196398)); lfg.Add(new FreqGain(230.081759247243, 0.0612659549892737)); lfg.Add(new FreqGain(255.866318897917, 0.0668005443605352)); lfg.Add(new FreqGain(282.926577933456, 0.0758917506709455)); lfg.Add(new FreqGain(311.330442067148, 0.0824530823635971)); lfg.Add(new FreqGain(341.14990292827, 0.0929637778755104)); lfg.Add(new FreqGain(372.461330102897, 0.100379371162514)); lfg.Add(new FreqGain(405.345788522409, 0.111984167288103)); lfg.Add(new FreqGain(439.889383835671, 0.123975744334166)); lfg.Add(new FreqGain(476.183638720577, 0.136237010524912)); lfg.Add(new FreqGain(514.325903454604, 0.148734117891156)); lfg.Add(new FreqGain(554.419804479247, 0.165502936111769)); lfg.Add(new FreqGain(596.575735167586, 0.178043988212559)); lfg.Add(new FreqGain(640.911393547776, 0.194349156663897)); lfg.Add(new FreqGain(687.552372358488, 0.209865869797881)); lfg.Add(new FreqGain(736.632807529586, 0.22500194685938)); lfg.Add(new FreqGain(788.296092007413, 0.243525065270957)); lfg.Add(new FreqGain(842.695662798627, 0.257649467879212)); lfg.Add(new FreqGain(899.99587021156, 0.273803874204412)); lfg.Add(new FreqGain(960.372939556513, 0.28709311052957)); lfg.Add(new FreqGain(1024.01603705869, 0.299481257886807)); lfg.Add(new FreqGain(1091.12845347812, 0.309245022903803)); lfg.Add(new FreqGain(1161.92892096669, 0.317179867687928)); lfg.Add(new FreqGain(1236.65308108085, 0.321207380680425)); lfg.Add(new FreqGain(1315.55512467678, 0.318824411496162)); lfg.Add(new FreqGain(1398.90962772937, 0.307833522186889)); lfg.Add(new FreqGain(1487.01361103779, 0.289293331349614)); lfg.Add(new FreqGain(1580.18885643692, 0.261606526767296)); lfg.Add(new FreqGain(1678.7845176806, 0.228997685797403)); lfg.Add(new FreqGain(1783.18007079301, 0.197540714557954)); lfg.Add(new FreqGain(1893.78865663959, 0.17295074128593)); lfg.Add(new FreqGain(2011.06087804797, 0.156696169926535)); lfg.Add(new FreqGain(2135.48912539139, 0.148455185344538)); lfg.Add(new FreqGain(2267.61251860637, 0.154528024795868)); lfg.Add(new FreqGain(2408.02257075748, 0.157020651297763)); lfg.Add(new FreqGain(2557.3696992537, 0.147606277996199)); lfg.Add(new FreqGain(2716.3707366486, 0.131041736855722)); lfg.Add(new FreqGain(2885.81762489105, 0.0866347064265516)); lfg.Add(new FreqGain(3066.58751658265, -0.0166654973944371)); lfg.Add(new FreqGain(3259.65455639083, -0.191612322714693)); lfg.Add(new FreqGain(3466.1036780904, -0.432511035136432)); lfg.Add(new FreqGain(3687.14683149463, -0.658960079848589)); lfg.Add(new FreqGain(3924.14215377249, -0.762774466055965)); lfg.Add(new FreqGain(4178.61672801844, -0.72195332419533)); lfg.Add(new FreqGain(4452.29373750316, -0.589733799295838)); lfg.Add(new FreqGain(4747.12503915768, -0.42970971679252)); lfg.Add(new FreqGain(5065.3304615832, -0.232527169811399)); lfg.Add(new FreqGain(5409.44550497149, -0.0355174224726339)); lfg.Add(new FreqGain(5782.37961614996, 0.226790461488208)); lfg.Add(new FreqGain(6187.48787900699, 0.570687924885134)); lfg.Add(new FreqGain(6628.65986711531, 0.902844690346035)); lfg.Add(new FreqGain(7110.43065099071, 0.97846591522975)); lfg.Add(new FreqGain(7638.12068410502, 0.785508262062104)); lfg.Add(new FreqGain(8218.013729816, 0.635399466540685)); lfg.Add(new FreqGain(8857.58547111898, 0.525129410649112)); lfg.Add(new FreqGain(9565.80048575836, 0.366859907213853)); lfg.Add(new FreqGain(10353.5026895216, 0.447897246086743)); lfg.Add(new FreqGain(11233.9354678215, 0.36565051131466)); lfg.Add(new FreqGain(12223.4446965003, 0.489904439751699)); lfg.Add(new FreqGain(13342.444347283, 0.338111293138435)); lfg.Add(new FreqGain(14616.7666969568, 0.237275309909941)); lfg.Add(new FreqGain(16079.5885672628, 0.1220539710691)); lfg.Add(new FreqGain(17774.2422466263, 0.0725148136373865)); lfg.Add(new FreqGain(19758.4244207167, 0.00128859185038382)); lfg.Add(new FreqGain(22110.6876081231, 6.13639214105897E-05)); return(lfg); }