Example #1
0
        public static SpectrumRendererData Create(IOutput output, int width, int height, int count, int fftSize, bool showPeaks, bool highCut)
        {
            var data = new SpectrumRendererData()
            {
                Output   = output,
                Width    = width,
                Height   = height,
                Count    = count,
                FFTSize  = fftSize,
                Samples  = output.GetBuffer(fftSize),
                Values   = new float[count],
                Elements = new Int32Rect[count]
            };

            if (showPeaks)
            {
                data.Peaks = new Int32Rect[count];
                data.Holds = new int[count];
            }
            if (highCut)
            {
                data.FFTRange = data.Samples.Length - (data.Samples.Length / 4);
            }
            else
            {
                data.FFTRange = data.Samples.Length;
            }
            data.SamplesPerElement = Math.Max(data.FFTRange / count, 1);
            data.Step = width / count;
            return(data);
        }
Example #2
0
        private static void Render(BitmapHelper.RenderInfo info, SpectrumRendererData rendererData)
        {
            var elements = rendererData.Elements;
            var peaks    = rendererData.Peaks;

            BitmapHelper.Clear(info);

            for (var a = 0; a < rendererData.Count; a++)
            {
                BitmapHelper.DrawRectangle(
                    info,
                    elements[a].X,
                    elements[a].Y,
                    elements[a].Width,
                    elements[a].Height
                    );
                if (peaks != null)
                {
                    if (peaks[a].Y >= elements[a].Y)
                    {
                        continue;
                    }
                    BitmapHelper.DrawRectangle(
                        info,
                        peaks[a].X,
                        peaks[a].Y,
                        peaks[a].Width,
                        peaks[a].Height
                        );
                }
            }
        }
Example #3
0
        private static void UpdateValues(SpectrumRendererData data)
        {
            var samples = data.Samples;
            var values  = data.Values;

            if (data.SamplesPerElement > 1)
            {
                for (int a = 0, b = 0; a < data.FFTRange && b < values.Length; a += data.SamplesPerElement, b++)
                {
                    var value = default(float);
                    for (var c = 0; c < data.SamplesPerElement; c++)
                    {
                        value = Math.Max(samples[a + c], value);
                    }
                    values[b] = ToDecibelFixed(value);
                }
            }
            else
            {
                //Not enough samples to fill the values, do the best we can.
                for (int a = 0; a < data.Count; a++)
                {
                    var value = samples[a];
                    values[a] = ToDecibelFixed(value);
                }
            }
        }
Example #4
0
        public static SpectrumRendererData Create(IOutput output, int width, int height, int count, int fftSize, int holdInterval, int updateInterval, int smoothingFactor, int amplitude, bool showPeaks, bool highCut)
        {
            var data = new SpectrumRendererData()
            {
                Width          = width,
                Height         = height,
                Count          = count,
                FFTSize        = fftSize,
                HoldInterval   = holdInterval,
                UpdateInterval = updateInterval,
                Smoothing      = smoothingFactor,
                Amplitude      = (float)amplitude / 500,
                Samples        = output.GetBuffer(fftSize),
                Values         = new float[count],
                Elements       = new Int32Rect[count]
            };

            if (showPeaks)
            {
                data.Peaks = new Int32Rect[count];
                data.Holds = new int[count];
            }
            if (highCut)
            {
                data.FFTRange = data.Samples.Length - (data.Samples.Length / 4);
            }
            else
            {
                data.FFTSize = data.Samples.Length;
            }
            data.SamplesPerElement = Math.Max(data.FFTRange / count, 1);
            data.Step = width / count;
            return(data);
        }
        public static SpectrumRendererData Create(EnhancedSpectrumRenderer renderer, int width, int height, int[] bands, int fftSize, bool showPeaks, bool showRms, bool showCrest)
        {
            var data = new SpectrumRendererData()
            {
                Renderer      = renderer,
                Width         = width,
                Height        = height,
                Bands         = bands,
                MinBand       = bands[0],
                MaxBand       = bands[bands.Length - 1],
                FFTSize       = fftSize,
                Samples       = renderer.Output.GetBuffer(fftSize),
                Values        = new float[bands.Length],
                ValueElements = new Int32Rect[bands.Length]
            };

            if (showRms)
            {
                data.Rms         = new float[bands.Length];
                data.RmsElements = new Int32Rect[bands.Length];
                if (showCrest)
                {
                    data.CrestPoints = new Int32Point[bands.Length];
                }
            }
            if (showPeaks)
            {
                data.PeakElements = new Int32Rect[bands.Length];
                data.Holds        = new int[bands.Length];
            }
            return(data);
        }
        private static void UpdateValues(SpectrumRendererData data)
        {
            var bands    = data.Bands;
            var position = default(int);

            data.ValuePeak = 0;
            data.RmsPeak   = 0;

            for (int a = FrequencyToIndex(data.MinBand, data.FFTSize, data.Rate), b = a; a < data.FFTSize; a++)
            {
                var frequency = IndexToFrequency(a, data.FFTSize, data.Rate);
                while (frequency > bands[position])
                {
                    if (position < (bands.Length - 1))
                    {
                        UpdateValue(data, position, b, a);
                        b = a;
                        position++;
                    }
                    else
                    {
                        UpdateValue(data, position, b, a);
                        return;
                    }
                }
            }
        }
Example #7
0
        private static void UpdateValues(SpectrumRendererData data)
        {
            var samples = data.Samples;

            if (data.SamplesPerElement > 1)
            {
                for (int a = 0, b = 0; a < data.FFTRange; a += data.SamplesPerElement, b++)
                {
                    var value = 0.0f;
                    for (var c = 0; c < data.SamplesPerElement; c++)
                    {
                        var boost = (float)(1.0f + a * data.Amplitude);
                        value += (float)(Math.Sqrt(samples[a + c] * boost) * SCALE_FACTOR);
                    }
                    data.Values[b] = Math.Min(Math.Max(value / data.SamplesPerElement, 0), 1);
                }
            }
            else
            {
                //Not enough samples to fill the values, do the best we can.
                for (int a = 0; a < data.Count; a++)
                {
                    var boost = (float)(1.0f + a * data.Amplitude);
                    var value = (float)(Math.Sqrt(samples[a] * boost) * SCALE_FACTOR);
                    data.Values[a] = Math.Min(Math.Max(value, 0), 1);
                }
            }
        }
Example #8
0
        private static void UpdatePeaks(SpectrumRendererData data)
        {
            var duration = Convert.ToInt32(
                Math.Min(
                    (DateTime.UtcNow - data.LastUpdated).TotalMilliseconds,
                    data.UpdateInterval * 100
                    )
                );

            var peaks    = data.Peaks;
            var holds    = data.Holds;
            var elements = data.Elements;

            var fast = data.Height / 4;

            for (int a = 0; a < data.Count; a++)
            {
                if (elements[a].Y < peaks[a].Y)
                {
                    peaks[a].X      = a * data.Step;
                    peaks[a].Width  = data.Step;
                    peaks[a].Height = 1;
                    peaks[a].Y      = elements[a].Y;
                    holds[a]        = data.HoldInterval + ROLLOFF_INTERVAL;
                }
                else if (elements[a].Y > peaks[a].Y && peaks[a].Y < data.Height - 1)
                {
                    if (holds[a] > 0)
                    {
                        if (holds[a] < data.HoldInterval)
                        {
                            var distance  = 1 - ((float)holds[a] / data.HoldInterval);
                            var increment = fast * (distance * distance * distance);
                            if (peaks[a].Y < data.Height - increment)
                            {
                                peaks[a].Y += (int)Math.Round(increment);
                            }
                            else if (peaks[a].Y < data.Height - 1)
                            {
                                peaks[a].Y = data.Height - 1;
                            }
                        }
                        holds[a] -= duration;
                    }
                    else if (peaks[a].Y < data.Height - fast)
                    {
                        peaks[a].Y += fast;
                    }
                    else if (peaks[a].Y < data.Height - 1)
                    {
                        peaks[a].Y = data.Height - 1;
                    }
                }
            }

            data.LastUpdated = DateTime.UtcNow;
        }
 private static void UpdateElementsSmooth(SpectrumRendererData data)
 {
     UpdateElementsSmooth(data.Values, data.ValueElements, data.Width, data.Height, data.Renderer.SmoothingFactor.Value, Orientation.Vertical);
     if (data.Rms != null && data.RmsElements != null)
     {
         UpdateElementsSmooth(data.Rms, data.RmsElements, data.Width, data.Height, data.Renderer.SmoothingFactor.Value, Orientation.Vertical);
     }
     if (data.Rms != null && data.CrestPoints != null)
     {
         UpdateCrestPointsSmooth(data.Values, data.Rms, data.CrestPoints, data.Width, data.Height, data.Renderer.SmoothingFactor.Value);
     }
 }
 private static void UpdateElementsFast(SpectrumRendererData data)
 {
     UpdateElementsFast(data.Values, data.ValueElements, data.Width, data.Height, Orientation.Vertical);
     if (data.Rms != null && data.RmsElements != null)
     {
         UpdateElementsFast(data.Rms, data.RmsElements, data.Width, data.Height, Orientation.Vertical);
     }
     if (data.Rms != null && data.CrestPoints != null)
     {
         UpdateCrestPointsFast(data.Values, data.Rms, data.CrestPoints, data.Width, data.Height);
     }
 }
Example #11
0
        private static void UpdateElementsSmooth(SpectrumRendererData data)
        {
            var values   = data.Values;
            var elements = data.Elements;

            var fast = (float)data.Height / data.Smoothing;

            for (var a = 0; a < data.Count; a++)
            {
                var barHeight = Convert.ToInt32(values[a] * data.Height);
                elements[a].X     = a * data.Step;
                elements[a].Width = data.Step;
                if (barHeight > 0)
                {
                    var difference = Math.Abs(elements[a].Height - barHeight);
                    if (difference > 0)
                    {
                        if (difference < 2)
                        {
                            if (barHeight > elements[a].Height)
                            {
                                elements[a].Height++;
                            }
                            else if (barHeight < elements[a].Height)
                            {
                                elements[a].Height--;
                            }
                        }
                        else
                        {
                            var distance = (float)difference / barHeight;
                            //TODO: We should use some kind of easing function.
                            //var increment = distance * distance * distance;
                            //var increment = 1 - Math.Pow(1 - distance, 5);
                            var increment = distance;
                            if (barHeight > elements[a].Height)
                            {
                                elements[a].Height = (int)Math.Min(elements[a].Height + Math.Min(Math.Max(fast * increment, 1), difference), data.Height);
                            }
                            else if (barHeight < elements[a].Height)
                            {
                                elements[a].Height = (int)Math.Max(elements[a].Height - Math.Min(Math.Max(fast * increment, 1), difference), 1);
                            }
                        }
                    }
                }
                else
                {
                    elements[a].Height = 1;
                }
                elements[a].Y = data.Height - elements[a].Height;
            }
        }
Example #12
0
        private static void UpdateElementsFast(SpectrumRendererData data)
        {
            var values   = data.Values;
            var elements = data.Elements;

            for (var a = 0; a < data.Count; a++)
            {
                var barHeight = Convert.ToInt32(values[a] * data.Height);
                elements[a].X     = a * data.Step;
                elements[a].Width = data.Step;
                if (barHeight > 0)
                {
                    elements[a].Height = barHeight;
                }
                else
                {
                    elements[a].Height = 1;
                }
                elements[a].Y = data.Height - elements[a].Height;
            }
        }
        private static void UpdateValue(SpectrumRendererData data, int band, int start, int end)
        {
            var samples = data.Samples;
            var value   = default(float);
            var rms     = default(float);
            var doRms   = data.Rms != null;
            var count   = end - start;

            if (count > 0)
            {
                for (var a = start; a < end; a++)
                {
                    value = Math.Max(samples[a], value);
                    if (doRms)
                    {
                        rms += samples[a] * samples[a];
                    }
                }
            }
            else
            {
                //If we don't have data then average the closest available bins.
                if (start > 0)
                {
                    start--;
                }
                if (end < data.FFTSize)
                {
                    end++;
                }
                count = end - start;
                for (var a = start; a < end; a++)
                {
                    value += samples[a];
                    if (doRms)
                    {
                        rms += samples[a] * samples[a];
                    }
                }
                value /= count;
            }

            if (value > 0)
            {
                data.ValuePeak = Math.Max(data.Values[band] = ToDecibelFixed(value), data.ValuePeak);
            }
            else
            {
                data.Values[band] = 0;
            }

            if (doRms)
            {
                if (count > 0)
                {
                    data.RmsPeak = Math.Max(data.Rms[band] = ToDecibelFixed(Convert.ToSingle(Math.Sqrt(rms / count))), data.RmsPeak);
                }
                else
                {
                    data.Rms[band] = 0;
                }
            }
        }
        private static void Render(BitmapHelper.RenderInfo valueRenderInfo, BitmapHelper.RenderInfo rmsRenderInfo, BitmapHelper.RenderInfo crestRenderInfo, SpectrumRendererData rendererData)
        {
            var valueElements = rendererData.ValueElements;
            var rmsElements   = rendererData.RmsElements;
            var crestPoints   = rendererData.CrestPoints;
            var peakElements  = rendererData.PeakElements;

            BitmapHelper.Clear(valueRenderInfo);

            for (var a = 0; a < valueElements.Length; a++)
            {
                BitmapHelper.DrawRectangle(
                    valueRenderInfo,
                    valueElements[a].X,
                    valueElements[a].Y,
                    valueElements[a].Width,
                    valueElements[a].Height
                    );
                if (rmsElements != null)
                {
                    if (rmsElements[a].Height > 0)
                    {
                        BitmapHelper.DrawRectangle(
                            rmsRenderInfo,
                            rmsElements[a].X,
                            rmsElements[a].Y,
                            rmsElements[a].Width,
                            rmsElements[a].Height
                            );
                    }
                }
                if (peakElements != null)
                {
                    if (peakElements[a].Y < valueElements[a].Y)
                    {
                        BitmapHelper.DrawRectangle(
                            valueRenderInfo,
                            peakElements[a].X,
                            peakElements[a].Y,
                            peakElements[a].Width,
                            peakElements[a].Height
                            );
                    }
                }
            }

            if (crestPoints != null)
            {
                for (var a = 0; a < crestPoints.Length - 1; a++)
                {
                    var point1 = crestPoints[a];
                    var point2 = crestPoints[a + 1];
                    BitmapHelper.DrawLine(
                        crestRenderInfo,
                        point1.X,
                        point1.Y,
                        point2.X,
                        point2.Y
                        );
                }
            }
        }