카테고리 없음

[기타] 일본의 저력.....

나스닥171819 2019. 6. 14. 11:25
728x90
반응형

일본 책들이나 중국 책들이 설명이 아주 친절하다.

 

한국에서 대학나온 사람들에게 삼각함수에 대해서 물어보면 대체로 머리를 긁는다.

 

난 문과라서 몰라....

 

내 전공이 아니라서 몰라...

 

wave 데이터를 1722Hz와 861Hz를 가산 한 정현파를 발생해 보아라...물어보면...

 

통신 공학을 전공한 사람이라면 시간은 걸리겠지만 대답 할 수 있다고 치더라고 

 

거의 대부분의 사람들은 대답을 못할 것이다.

 

암기 위주의 교육으로는 응용이 되지 못하기 때문이다.

 

 

 

맨땅에 해딩하는 시대는 끝났다.

 

중복 투자를 하지 않는 것이 생산성 향상에 가장 필수다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

https://tomosoft.jp/design/?p=9127

 

C#によるWaveデータのFFT処理

Visual Studio Express 2013を使用し、C#言語によりWaveファイル形式でWaveデータに対して、FFT処理を行います。「C#によるWaveデータの作成」によりFFT処理を行うWaveファイルを作成し、FFT処理を行いその処理結果を表示します。次の表示は、1722Hzと861Hzを加算したデータ長100msの正弦波に対して、FFT処理を行った結果を示します。 FFT処理ライブラリの追加 FFTの計算には、Math.NET Numericsを使用します。Math.NET Numeric

tomosoft.jp

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

wave 데이터는 1722Hz와 861Hz를 가산 한 정현파를 발생하기 위해 28 번째 줄에서 31 번째 줄을 다음과 같이 변경합니다. 또한 발생한 1722Hz와 861Hz를 가산 한 정현파는 FFT 처리를하면 1722Hz 샘플 포인트의 80 번째 861Hz는 샘플 포인트의 40 번째 피크입니다.

1

2

3

4

5

6

7

8

// 1722Hzと861Hzを加算した正弦波を作る。

double Wave = 0;

 

Wave += Math.Sin(Radian * 1722);

Wave += Math.Sin(Radian * 861);

Wave /= 2;

 

short Data = (short)(Wave * 30000);

샘플링주기가 22.675736961451μsec (= 1 / 44,100)에 2048 포인트 FFT하면 주파수 분해능은 1 / (2048 * 22.67573696145μ) = 21.533203125Hz입니다. 
샘플 포인트의 40 번째 : 21.533203125Hz * 40 = 861Hz

샘플 포인트의 80 번째 : 21.533203125Hz * 80 = 1722Hz

C #에 따르면 Wave 데이터 FFT 처리 프로그램의 작성

설치 한 Math.NET Numerics를 사용하여 FFT 계산합니다. FFT 샘플 수는 2048 포인트로했습니다.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

using System.Numerics;

using MathNet.Numerics;

using MathNet.Numerics.IntegralTransforms;

 

public void computeFFT(int[] soundvalues)

{

    //convert int to complex

    for (int i = 0; i < windowSize; i++)

    {

        complexData[i] = new Complex((double)soundvalues[i], 0);   // 

    }

 

    //run FFT

    Fourier.Forward(complexData, FourierOptions.Matlab); // arbitrary length

}

  • 변수 "windowSize"는 "2048"로합니다.
  • 10 번째 줄에서 Complex 인스턴스는 입력 한 Wave 데이터를 복소수 데이터로 변환합니다.

C #에 따르면 Wave 데이터 FFT 처리 결과 표시 프로그램 만들기

FFT 처리 결과를 막대 그램으로 표시합니다. 처리 방법에 대해서는 " C #을 사용하여 Wave 파일의 데이터를 이용한 파형 표시 "를 참조하십시오. 또한 다음 부분을 변경합니다.

  • 제목 및 축 레이블 변경
  • test.ChartType : SeriesChartType.Column

2048 포인트 샘플 값의 표시는 다음과 같이 복소수 "value"의 절대 값으로 표시합니다.

1

2

3

4

5

//グラフのデータを追加

for (int i = 0; i < value.Length; i++)

{

    test.Points.AddXY(i, value[i].Magnitude);

}

 

 

보너스

 

 

http://semitennis.blog100.fc2.com/blog-entry-82.html

 

 

 

 

 

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Windows.Forms;

using System.Windows.Forms.DataVisualization.Charting;

 

namespace SinWave

{

    public partial class Form1 : Form

    {

        // 波形サイズ

        int size = 1024;

        // サンプリング周波数

        int fs = 1800;

        // DFT用データ

        double[] re;

        double[] im;

        // FFT用データ

        double[] reFFT;

        double[] imFFT;

        double[] reFFT_2;

        double[] imFFT_2;

        // 窓関数

        public enum WindowFunc

        {

            Hamming,

            Hanning,

            Blackman,

            Rectangular

        }

 

        // コンストラクタ

        public Form1()

        {

            InitializeComponent();

            plot();

        }

 

        // 正弦波生成

        public double Sin(int freq, int i)

        {

            double sin = 0.2 * Math.Sin(2 * (freq*fs/180) * i * Math.PI / fs);

            return sin;

        }

 

        // DFT

        public void DFT(int n, double[] inputRe, out double[] real, out double[] imag)

        {

            real = new double[n];

            imag = new double[n];

 

            for (int i = 0; i < n; i++)

            {

                real[i] = 0.0;

                imag[i] = 0.0;

 

                for (int j = 0; j < n; j++)

                {

                    real[i]   += inputRe[j] * Math.Cos(2 * Math.PI * i * j / fs);

                    imag[i] += inputRe[j] * -(Math.Sin(2 * Math.PI * i * j / fs));

                }

            }

        }

 

        // FFT

        public static void FFT(double[] inputRe, double[] inputIm, out double[] outputRe, out double[] outputIm, int bitSize)

        {

            int dataSize = 1 << bitSize;

            int[] reverseBitArray = BitScrollArray(dataSize);

 

            outputRe = new double[dataSize];

            outputIm = new double[dataSize];

 

            // バタフライ演算のための置き換え

            for (int i = 0; i < dataSize; i++)

            {

                outputRe[i] = inputRe[reverseBitArray[i]];

                outputIm[i] = inputIm[reverseBitArray[i]];

            }

 

            // バタフライ演算

            for (int stage = 1; stage <= bitSize; stage++)

            {

                int butterflyDistance = 1 << stage;

                int numType = butterflyDistance >> 1;

                int butterflySize = butterflyDistance >> 1;

 

                double wRe = 1.0;

                double wIm = 0.0;

                double uRe = System.Math.Cos(System.Math.PI / butterflySize);

                double uIm = -System.Math.Sin(System.Math.PI / butterflySize);

 

                for (int type = 0; type < numType; type++)

                {

                    for (int j = type; j < dataSize; j += butterflyDistance)

                    {

                        int jp = j + butterflySize;

                        double tempRe = outputRe[jp] * wRe - outputIm[jp] * wIm;

                        double tempIm = outputRe[jp] * wIm + outputIm[jp] * wRe;

                        outputRe[jp] = outputRe[j] - tempRe;

                        outputIm[jp] = outputIm[j] - tempIm;

                        outputRe[j] += tempRe;

                        outputIm[j] += tempIm;

                    }

                    double tempWRe = wRe * uRe - wIm * uIm;

                    double tempWIm = wRe * uIm + wIm * uRe;

                    wRe = tempWRe;

                    wIm = tempWIm;

                }

            }

        }

 

        // ビットを左右反転した配列を返す

        private static int[] BitScrollArray(int arraySize)

        {

            int[] reBitArray = new int[arraySize];

            int arraySizeHarf = arraySize >> 1;

 

            reBitArray[0] = 0;

            for (int i = 1; i < arraySize; i <<= 1)

            {

                for (int j = 0; j < i; j++)

                    reBitArray[j + i] = reBitArray[j] + arraySizeHarf;

                arraySizeHarf >>= 1;

            }

            return reBitArray;

        }

 

        // 窓関数

        public static double[] Windowing(double[] data, WindowFunc windowFunc)

        {

            int size = data.Length;

            double[] windata = new double[size];

 

            for (int i = 0; i < size; i++)

            {

                double winValue = 0;

                // 各々の窓関数

                if (WindowFunc.Hamming == windowFunc)

                {

                    winValue = 0.54 - 0.46 * Math.Cos(2 * Math.PI * i / (size - 1));

                }

                else if (WindowFunc.Hanning == windowFunc)

                {

                    winValue = 0.5 - 0.5 * Math.Cos(2 * Math.PI * i / (size - 1));

                }

                else if (WindowFunc.Blackman == windowFunc)

                {

                    winValue = 0.42 - 0.5 * Math.Cos(2 * Math.PI * i / (size - 1))

                                    + 0.08 * Math.Cos(4 * Math.PI * i / (size - 1));

                }

                else if (WindowFunc.Rectangular == windowFunc)

                {

                    winValue = 1.0;

                }

                else

                {

                    winValue = 1.0;

                }

                // 窓関数を掛け算

                windata[i] = data[i] * winValue;

            }

            return windata;

        }

 

         //グラフ表示形式

        private void plot()

        {

            // chart1

            Series series1 = new Series("sinWave 1+5+10+50Hz");

            Series series1_mado = new Series("mado");

            // chart2

            Series series2 = new Series("DFT");

            Series series3 = new Series("FFT");

            Series series4 = new Series("FFT_mado");

            // DFT用データ

            double[] dftIn = new double[size];

            double[] dftInIm = new double[size];

            // 窓関数後データ

            double[] data = new double[size];

 

            // 波形生成

            for (int i = 0; i < size; i++)

            {

                dftIn[i] = Sin(1, i);

                dftIn[i] += Sin(5, i);

                dftIn[i] += Sin(10, i);

                dftIn[i] += Sin(50, i);

                series1.Points.AddXY(i, dftIn[i]);

                dftInIm[i] = 0.0;

            }

 

            // 窓関数

            data = Windowing(dftIn, WindowFunc.Hanning);

            for (int i = 0; i < size; i++)

            {

                series1_mado.Points.AddXY(i, data[i]);

            }

 

            // DFT

            DFT(size, dftIn, out re, out im);

 

            // FFT

            FFT(dftIn, dftInIm, out reFFT, out imFFT, 10);

            FFT(data, dftInIm, out reFFT_2, out imFFT_2, 10);

 

            // DFT波形表示

            for (int i = 0; i < size; i++)

            {

                if (i > 0)

                {

                    series2.Points.AddXY((double)i / (fs / 180), Math.Sqrt(re[i] * re[i] + im[i] * im[i]));

                    double x = (double)i * (180.0 / size);

                    double y = Math.Sqrt(reFFT[i] * reFFT[i] + imFFT[i] * imFFT[i]);

                    //series3.Points.AddXY((double)i * (180.0 / size), Math.Sqrt(reFFT[i] * reFFT[i] + imFFT[i] * imFFT[i]));

                    series3.Points.AddXY(x, y);

                    double y2 = Math.Sqrt(reFFT_2[i] * reFFT_2[i] + imFFT_2[i] * imFFT_2[i]);

                    series4.Points.AddXY(x, y2);

                }

            }

 

            series1.ChartType = SeriesChartType.Line; // グラフ形状

            series1_mado.ChartType = SeriesChartType.Line; // グラフ形状

            series2.ChartType = SeriesChartType.Line; // グラフ形状

            series3.ChartType = SeriesChartType.Line; // グラフ形状

            series4.ChartType = SeriesChartType.Line; // グラフ形状

 

            chart1.Series.Clear();

            chart1.Series.Add(series1);

            chart1.Series.Add(series1_mado);

            chart2.Series.Clear();

            chart2.Series.Add(series2);

            chart2.Series.Add(series3);

            chart2.Series.Add(series4);

 

            Axis ax = chart1.ChartAreas[0].AxisX;

            ax.MajorGrid.LineColor = Color.LightGray;

            Axis ay = chart1.ChartAreas[0].AxisY;

            ay.MajorGrid.LineColor = Color.LightGray;

 

            Axis ax2 = chart2.ChartAreas[0].AxisX;

            ax2.MajorGrid.LineColor = Color.LightGray;

            ax2.IsLogarithmic = true;

            Axis ay2 = chart2.ChartAreas[0].AxisY;

            ay2.MajorGrid.LineColor = Color.LightGray;

            ay2.IsLogarithmic = true;

        }

 

        // save file

        private void button1_Click(object sender, EventArgs e)

        {

            //SaveFileDialogクラスのインスタンスを作成

            SaveFileDialog sfd = new SaveFileDialog();

 

            //ダイアログを表示する

            if (sfd.ShowDialog() == DialogResult.OK)

            {

                System.IO.Stream stream;

                stream = sfd.OpenFile();

                if (stream != null)

                {

                    //ファイルに書き込む

                    System.IO.StreamWriter sw = new System.IO.StreamWriter(stream);

                    for (int i = 0; i < size; i++)

                    {

                        sw.Write((double)i/(fs/180) + "," + Math.Sqrt(re[i] * re[i] + im[i] * im[i]) + ","

                                        + (double)i * (180.0 / size) + "," + Math.Sqrt(reFFT[i] * reFFT[i] + imFFT[i] * imFFT[i]) + "\n");

                    }

                    sw.Close();

                    stream.Close();

                }

            }

        }

    }

}

반응형
댓글수0