示例#1
0
        public override EffectLayer Render(IGameState gamestate)
        {
            EffectLayer gradient_layer = new EffectLayer();

            //If Wave Size 0 Gradiant Stop Moving Animation
            if (Properties.GradientConfig.gradient_size == 0)
            {
                Properties.GradientConfig.shift_amount    += ((Utils.Time.GetMillisecondsSinceEpoch() - Properties.GradientConfig.last_effect_call) / 1000.0f) * 5.0f * Properties.GradientConfig.speed;
                Properties.GradientConfig.shift_amount     = Properties.GradientConfig.shift_amount % Effects.canvas_biggest;
                Properties.GradientConfig.last_effect_call = Utils.Time.GetMillisecondsSinceEpoch();

                Color selected_color = Properties.GradientConfig.brush.GetColorSpectrum().GetColorAt(Properties.GradientConfig.shift_amount, Effects.canvas_biggest);

                gradient_layer.Set(Properties.Sequence, selected_color);
            }
            else if (Properties.Sequence.type == KeySequenceType.Sequence)
            {
                using var temp_layer = new EffectLayer("Color Zone Effect", LayerEffects.GradientShift_Custom_Angle, Properties.GradientConfig);

                foreach (var key in Properties.Sequence.keys)
                {
                    gradient_layer.Set(key, temp_layer.Get(key));
                }
            }
            else
            {
                gradient_layer.DrawTransformed(
                    Properties.Sequence,
                    g =>
                {
                    var rect = new RectangleF(0, 0, Effects.canvas_width, Effects.canvas_height);
                    using var temp_layer_bitmap = new EffectLayer("Color Zone Effect", LayerEffects.GradientShift_Custom_Angle, Properties.GradientConfig, rect).GetBitmap();
                    g.DrawImage(temp_layer_bitmap, rect, rect, GraphicsUnit.Pixel);
                }
                    );
            }
            return(gradient_layer);
        }
        public override EffectLayer Render(IGameState gamestate)
        {
            try
            {
                //if (current_device != null)
                //current_device.Dispose();
                CheckForDeviceChange();

                // The system sound as a value between 0.0 and 1.0
                float system_sound_normalized = default_device.AudioEndpointVolume.MasterVolumeLevelScalar;

                // Scale the Maximum amplitude with the system sound if enabled, so that at 100% volume the max_amp is unchanged.
                // Replaces all Properties.MaxAmplitude calls with the scaled value
                float scaled_max_amplitude = Properties.MaxAmplitude * (Properties.ScaleWithSystemVolume ? system_sound_normalized : 1);

                float[] freqs = Properties.Frequencies.ToArray(); //Defined Frequencies

                double[] freq_results = new double[freqs.Length];

                if (previous_freq_results == null || previous_freq_results.Length < freqs.Length)
                {
                    previous_freq_results = new float[freqs.Length];
                }

                //Maintain local copies of fft, to prevent data overwrite
                Complex[] _local_fft          = new List <Complex>(_ffts).ToArray();
                Complex[] _local_fft_previous = new List <Complex>(_ffts_prev).ToArray();

                EffectLayer equalizer_layer = new EffectLayer();

                bool BgEnabled = false;
                switch (Properties.BackgroundMode)
                {
                case EqualizerBackgroundMode.EnabledOnSound:
                    foreach (var bin in _local_fft)
                    {
                        if (bin.X > 0.0005 || bin.X < -0.0005)
                        {
                            BgEnabled = true;
                            break;
                        }
                    }
                    break;

                case EqualizerBackgroundMode.AlwaysOn:
                    BgEnabled = true;
                    break;
                }


                // Use the new transform render method to draw the equalizer layer
                equalizer_layer.DrawTransformed(Properties.Sequence, g => {
                    // Here we draw the equalizer relative to our source rectangle and the DrawTransformed method handles sizing and positioning it correctly for us

                    // Draw a rectangle background over the entire source rect if bg is enabled
                    if (BgEnabled)
                    {
                        g.FillRectangle(new SolidBrush(Properties.DimColor), sourceRect);
                    }

                    g.CompositingMode = CompositingMode.SourceCopy;

                    int wave_step_amount = _local_fft.Length / (int)sourceRect.Width;

                    switch (Properties.EQType)
                    {
                    case EqualizerType.Waveform:
                        var halfHeight = sourceRect.Height / 2f;
                        for (int x = 0; x < (int)sourceRect.Width; x++)
                        {
                            float fft_val = _local_fft.Length > x * wave_step_amount ? _local_fft[x * wave_step_amount].X : 0.0f;
                            Brush brush   = GetBrush(fft_val, x, sourceRect.Width);
                            var yOff      = -Math.Max(Math.Min(fft_val / scaled_max_amplitude * 1000.0f, halfHeight), -halfHeight);
                            g.DrawLine(new Pen(brush), x, halfHeight, x, halfHeight + yOff);
                        }
                        break;

                    case EqualizerType.Waveform_Bottom:
                        for (int x = 0; x < (int)sourceRect.Width; x++)
                        {
                            float fft_val = _local_fft.Length > x * wave_step_amount ? _local_fft[x * wave_step_amount].X : 0.0f;
                            Brush brush   = GetBrush(fft_val, x, sourceRect.Width);
                            g.DrawLine(new Pen(brush), x, sourceRect.Height, x, sourceRect.Height - Math.Min(Math.Abs(fft_val / scaled_max_amplitude) * 1000.0f, sourceRect.Height));
                        }
                        break;

                    case EqualizerType.PowerBars:
                        //Perform FFT again to get frequencies
                        FastFourierTransform.FFT(false, (int)Math.Log(fftLength, 2.0), _local_fft);

                        while (flux_array.Count < freqs.Length)
                        {
                            flux_array.Add(0.0f);
                        }

                        int startF = 0;
                        int endF   = 0;

                        float threshhold = 300.0f;

                        for (int x = 0; x < freqs.Length - 1; x++)
                        {
                            startF = freqToBin(freqs[x]);
                            endF   = freqToBin(freqs[x + 1]);

                            float flux = 0.0f;

                            for (int j = startF; j <= endF; j++)
                            {
                                float curr_fft = (float)Math.Sqrt(_local_fft[j].X * _local_fft[j].X + _local_fft[j].Y * _local_fft[j].Y);
                                float prev_fft = (float)Math.Sqrt(_local_fft_previous[j].X * _local_fft_previous[j].X + _local_fft_previous[j].Y * _local_fft_previous[j].Y);

                                float value     = curr_fft - prev_fft;
                                float flux_calc = (value + Math.Abs(value)) / 2;
                                if (flux < flux_calc)
                                {
                                    flux = flux_calc;
                                }

                                flux = flux > threshhold ? 0.0f : flux;
                            }

                            flux_array[x] = flux;
                        }

                        //System.Diagnostics.Debug.WriteLine($"flux max: {flux_array.Max()}");

                        float bar_width = sourceRect.Width / (float)(freqs.Length - 1);

                        for (int f_x = 0; f_x < freq_results.Length - 1; f_x++)
                        {
                            float fft_val = flux_array[f_x] / scaled_max_amplitude;

                            fft_val = Math.Min(1.0f, fft_val);

                            if (previous_freq_results[f_x] - fft_val > 0.10)
                            {
                                fft_val = previous_freq_results[f_x] - 0.15f;
                            }

                            float x      = f_x * bar_width;
                            float y      = sourceRect.Height;
                            float height = fft_val * sourceRect.Height;

                            previous_freq_results[f_x] = fft_val;

                            Brush brush = GetBrush(-(f_x % 2), f_x, freq_results.Length - 1);

                            g.FillRectangle(brush, x, y - height, bar_width, height);
                        }
                        break;
                    }
                }, sourceRect);


                var hander = NewLayerRender;
                if (hander != null)
                {
                    hander.Invoke(equalizer_layer.GetBitmap());
                }
                return(equalizer_layer);
            }
            catch (Exception exc)
            {
                Global.logger.Error("Error encountered in the Equalizer layer. Exception: " + exc.ToString());
                return(new EffectLayer());
            }
        }