public static void Logarithm(double *src, int srcWidth, double srcMinFrequency, double srcMaxFrequency, double *dst, int dstWidth, ILogarithm log) { if (log != null) { double scale = (srcWidth - 1) / (srcMaxFrequency - srcMinFrequency); double minMel = log.Log(srcMinFrequency); double maxMel = log.Log(srcMaxFrequency); double mscale = (maxMel - minMel) / dstWidth; for (int i = 0; i < dstWidth; i++) { double x1 = (log.ILog(i * mscale + minMel) - srcMinFrequency) * scale; double x2 = (log.ILog((i + 1) * mscale + minMel) - srcMinFrequency) * scale; dst[i] = Max(src, srcWidth, x1, x2); } } else { double scale = (double)(srcWidth - 1) / dstWidth; for (int i = 0; i < dstWidth; i++) { double x1 = i * scale; double x2 = x1 + scale; dst[i] = Max(src, srcWidth, x1, x2); } } }
public static void Logarithm(ReadOnlySpan <double> src, double srcMinFrequency, double srcMaxFrequency, Span <double> dst, ILogarithm log) { src.Handle(dst, (ReadOnlySpan <double> @in, Span <double> @out) => { var srcWidth = @in.Length; var dstWidth = @out.Length; if (log != null) { var logChanged = logarithmCache.Log != log; if (logChanged) { logarithmCache.Log = log; } if (logChanged || logarithmCache.MinFrequency != srcMinFrequency || logarithmCache.MaxFrequency != srcMaxFrequency) { logarithmCache.MinFrequency = srcMinFrequency; logarithmCache.MaxFrequency = srcMaxFrequency; logarithmCache.MinFrequencyLog = log.Log(srcMinFrequency); logarithmCache.MaxFrequencyLog = log.Log(srcMaxFrequency); } if (logChanged || logarithmCache.Width != dstWidth) { double scale = (srcWidth - 1) / (srcMaxFrequency - srcMinFrequency); double minMel = logarithmCache.MinFrequencyLog; double maxMel = logarithmCache.MaxFrequencyLog; double mscale = (maxMel - minMel) / dstWidth; var cache = new double[dstWidth + 1]; for (int i = 0; i <= dstWidth; i++) { cache[i] = (log.ILog(i * mscale + minMel) - srcMinFrequency) * scale; } logarithmCache.Width = dstWidth; logarithmCache.Data = cache; } fixed(double *cache = logarithmCache.Data) { for (int i = 0; i < dstWidth; i++) { @out[i] = Max(@in, cache[i], cache[i + 1]); } } } else { double scale = (double)(srcWidth - 1) / dstWidth; for (int i = 0; i < dstWidth; i++) { double x1 = i * scale; double x2 = x1 + scale; @out[i] = Max(@in, x1, x2); } } }); }