Ejemplo n.º 1
0
        // Событие записи для объекта Wave - анализ сигнала с управлением автоподстройкой и световыми эффектами
        private void WaveIn_DataAvailable(object sender, WaveInEventArgs e)
        {
            int samplesRecorded = e.BytesRecorded / (waveIn.WaveFormat.BitsPerSample / 8); // размер полученного буфера
            int numChannels = waveIn.WaveFormat.Channels;
            float sampleRate = waveIn.WaveFormat.SampleRate;

            UnionStruct u = new UnionStruct();
            u.bytes = e.Buffer;

            Complex[] data = new Complex[size]; // буфер для БПФ

            float currentAmplitude = 0;

            // готовим сигнал к БПФ
            int j = 0;

            for (int i = 0; i < samplesRecorded && j < size; i += numChannels)
            {
                float left = u.floats[i];
                float right = u.floats[i + (numChannels - 1)];

                float avg = (left + right) / 2;

                if (Math.Abs(avg) > currentAmplitude)
                {
                    currentAmplitude = Math.Abs(avg);
                }

                //float value = avg * (float)FastFourierTransform.BlackmannHarrisWindow(j, size);
                float value = avg * blackmanWindow(j, size);

                data[j].X = value;
                data[j].Y = 0;

                j++;
            }

            if (currentAmplitude > inNoiseLevel)
            {
                stopWatch.Reset();

                if (agcCheckBox.Checked)
                {
                    float regulatorRatio = currentAmplitude * gain < targetAmplitude ? upRegulatorRatio : downRegulatorRatio;

                    gain += regulatorRatio * (targetAmplitude / currentAmplitude - gain);

                    for (int i = 0; i < j; i++)
                    {
                        data[i].X *= gain;
                    }
                }
                // остаток наполняем нулями
                while (j < size)
                {
                    data[j].X = 0;
                    data[j].Y = 0;

                    j++;
                }

                FastFourierTransform.FFT(true, log2N, data); // выполняем быстрое преобразование Фурье

                int maxI = -1; // индекс макисмальной амплитуды
                float max = -1; // значение максимальной амплитуды

                int band = 0;

                for (int i = 0; i < numBands; i++)
                {
                    values[i] = 0;
                }

                for (int i = 0; i < size / 2; i++)
                {
                    float currentFreq = sampleRate * i / size;

                    if (band < numBands - 1 && currentFreq > bandDefs[band])
                    {
                        band++;
                    }

                    float amp = data[i].X * data[i].X + data[i].Y * data[i].Y;

                    if (amp > outNoiseLevel)
                    {
                        values[band] += amp;
                    }

                    if (amp > max)
                    {
                        max = amp;
                        maxI = i;
                    }
                }

                for (int i = 0; i < numBands; i++)
                {
                    values[i] = (float)Math.Sqrt(values[i]) * valuesScale[i];
                }
            }
            else
            {
                stopWatch.Stop();
                double seconds = stopWatch.Elapsed.TotalSeconds;
                stopWatch.Start();

                if (seconds > downtimeInSeconds && fadeCheckBox.Checked)
                {
                    light_effects(values, RGB_FADE_EFFECT);
                }
                else
                {
                    for (int i = 0; i < numBands; i++)
                    {
                        values[i] = 0;
                    }
                }
            }

            try
            {
                connectedPort.Write("set rgb " + limit(values[0]) + " " + limit(values[1]) + " " + limit(values[2]) + "\n");
            }
            catch (TimeoutException)
            {
                MessageBox.Show("Последовательный порт " + connectedPort.PortName +
                        " стал недоступен. Попробуйте подключиться ещё раз", "Ошибка",
                        MessageBoxButtons.OK, MessageBoxIcon.Exclamation);

                connected = false;

                if (connectedPort.IsOpen)
                {
                    connectedPort.Close();
                }

                waveIn.StopRecording();
            }
        }
Ejemplo n.º 2
0
        // Событие записи для объекта Wave - анализ сигнала с управлением автоподстройкой и световыми эффектами
        private void WaveIn_DataAvailable(object sender, WaveInEventArgs e)
        {
            int   samplesRecorded = e.BytesRecorded / (waveIn.WaveFormat.BitsPerSample / 8); // размер полученного буфера
            int   numChannels     = waveIn.WaveFormat.Channels;
            float sampleRate      = waveIn.WaveFormat.SampleRate;

            UnionStruct u = new UnionStruct();

            u.bytes = e.Buffer;

            Complex[] data = new Complex[size]; // буфер для БПФ

            float currentAmplitude = 0;

            // готовим сигнал к БПФ
            int j = 0;

            for (int i = 0; i < samplesRecorded && j < size; i += numChannels)
            {
                float left  = u.floats[i];
                float right = u.floats[i + (numChannels - 1)];

                float avg = (left + right) / 2;

                if (Math.Abs(avg) > currentAmplitude)
                {
                    currentAmplitude = Math.Abs(avg);
                }

                //float value = avg * (float)FastFourierTransform.BlackmannHarrisWindow(j, size);
                float value = avg * blackmanWindow(j, size);

                data[j].X = value;
                data[j].Y = 0;

                j++;
            }

            if (currentAmplitude > inNoiseLevel)
            {
                stopWatch.Reset();

                if (agcCheckBox.Checked)
                {
                    float regulatorRatio = currentAmplitude * gain < targetAmplitude ? upRegulatorRatio : downRegulatorRatio;

                    gain += regulatorRatio * (targetAmplitude / currentAmplitude - gain);

                    for (int i = 0; i < j; i++)
                    {
                        data[i].X *= gain;
                    }
                }
                // остаток наполняем нулями
                while (j < size)
                {
                    data[j].X = 0;
                    data[j].Y = 0;

                    j++;
                }

                FastFourierTransform.FFT(true, log2N, data); // выполняем быстрое преобразование Фурье

                int   maxI = -1;                             // индекс макисмальной амплитуды
                float max  = -1;                             // значение максимальной амплитуды

                int band = 0;

                for (int i = 0; i < numBands; i++)
                {
                    values[i] = 0;
                }

                for (int i = 0; i < size / 2; i++)
                {
                    float currentFreq = sampleRate * i / size;

                    if (band < numBands - 1 && currentFreq > bandDefs[band])
                    {
                        band++;
                    }

                    float amp = data[i].X * data[i].X + data[i].Y * data[i].Y;

                    if (amp > outNoiseLevel)
                    {
                        values[band] += amp;
                    }

                    if (amp > max)
                    {
                        max  = amp;
                        maxI = i;
                    }
                }

                for (int i = 0; i < numBands; i++)
                {
                    values[i] = (float)Math.Sqrt(values[i]) * valuesScale[i];
                }
            }
            else
            {
                stopWatch.Stop();
                double seconds = stopWatch.Elapsed.TotalSeconds;
                stopWatch.Start();

                if (seconds > downtimeInSeconds && fadeCheckBox.Checked)
                {
                    light_effects(values, RGB_FADE_EFFECT);
                }
                else
                {
                    for (int i = 0; i < numBands; i++)
                    {
                        values[i] = 0;
                    }
                }
            }

            try
            {
                connectedPort.Write("set rgb " + limit(values[0]) + " " + limit(values[1]) + " " + limit(values[2]) + "\n");
            }
            catch (TimeoutException)
            {
                MessageBox.Show("Последовательный порт " + connectedPort.PortName +
                                " стал недоступен. Попробуйте подключиться ещё раз", "Ошибка",
                                MessageBoxButtons.OK, MessageBoxIcon.Exclamation);

                connected = false;

                if (connectedPort.IsOpen)
                {
                    connectedPort.Close();
                }

                waveIn.StopRecording();
            }
        }