0

nAudio の WaveIn 関数から波形をグラフ化することを検討しています。私がやろうとしていることを正確に達成する例をオンラインで見つけましたが、外部のグラフ作成ライブラリ (Scottplot) を使用し、C# でプログラムされています (VB が必要です)。私は正常に標準チャートにグラフを表示し、基本的にすべてのコードを翻訳しました。コンパイルはできますが、私のストリームは空です。私はこれを何週間も解決しようとしましたが、うまくいきませんでした。

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;

    using NAudio.Wave; // installed with nuget
    using NAudio.CoreAudioApi;
    using System.Numerics;


    namespace microphone
    {
        public partial class Form1 : Form
        {

            public WaveIn wi;
            public BufferedWaveProvider bwp;
            //public Int32 envelopeMax;

            private int RATE = 44100; // sample rate of the sound card
            private int BUFFERSIZE = (int) Math.Pow(2,13); // must be a multiple of 2
            //private int BUFFERSIZE = 2048; // must be a multiple of 2

            public Form1()
            {
                InitializeComponent();

                // see what audio devices are available
                int devcount = WaveIn.DeviceCount;
                Console.Out.WriteLine("Device Count: {0}.", devcount);

                // get the WaveIn class started
                WaveIn wi = new WaveIn();
                wi.DeviceNumber = 0;
                wi.WaveFormat = new NAudio.Wave.WaveFormat(RATE, 1);

                // create a wave buffer and start the recording
                wi.DataAvailable += new EventHandler<WaveInEventArgs>(wi_DataAvailable);
                bwp = new BufferedWaveProvider(wi.WaveFormat);
                bwp.BufferLength = BUFFERSIZE * 2;

                bwp.DiscardOnBufferOverflow = true;
                wi.StartRecording();

            }

            // adds data to the audio recording buffer
            void wi_DataAvailable(object sender, WaveInEventArgs e)
            {
                bwp.AddSamples(e.Buffer, 0, e.BytesRecorded);
            }

            public void timer1_Tick(object sender, EventArgs e)
            {
                // read the bytes from the stream
                int frameSize = BUFFERSIZE;
                var frames = new byte[frameSize];
                bwp.Read(frames, 0, frameSize);
                if (frames.Length == 0) return;
                if (frames[frameSize - 2] == 0)
                {
                    label1.Text = "removed";
                    return;
                }
                else {
                    label1.Text = "graphing";
                }


                // convert it to int32 manually (and a double for scottplot)
                int SAMPLE_RESOLUTION = 16;
                int BYTES_PER_POINT = SAMPLE_RESOLUTION / 8;
                Int32[] vals = new Int32[frames.Length/BYTES_PER_POINT];
                double[] Ys = new double[frames.Length / BYTES_PER_POINT];
                double[] Xs = new double[frames.Length / BYTES_PER_POINT];
    //            double[] Ys2 = new double[frames.Length / BYTES_PER_POINT];
    //            double[] Xs2 = new double[frames.Length / BYTES_PER_POINT];
                for (int i=0; i<vals.Length; i++)

                {
                    // bit shift the byte buffer into the right variable format
                    byte hByte = frames[i * 2 + 1];
                    byte lByte = frames[i * 2 + 0];
                    vals[i] = (int)(short)((hByte << 8) | lByte);
                    Xs[i] = i;
                    Ys[i] = vals[i];
    //                Xs2[i] = (double)i/Ys.Length*RATE/1000.0; // units are in kHz
                }


                chart1.ChartAreas[0].AxisX.Maximum = 400;
                chart1.ChartAreas[0].AxisX.Minimum= 0;

                chart1.Series[0].Points.DataBindXY(Xs, Ys);

                //update scottplot (FFT, frequency domain)

                /* Ys2 = FFT(Ys);

                chart2.ChartAreas[0].AxisX.Maximum = 10;
                chart2.ChartAreas[0].AxisX.Minimum = 0;            chart2.Series[0].Points.DataBindXY(Xs2.Take(Xs2.Length / 2).ToArray(), Ys2.Take(Ys2.Length / 2).ToArray());

                // update the displays
                Application.DoEvents();
                */

            }

            //public double[] FFT(double[] data)
            //{
            //    double[] fft = new double[data.Length]; // this is where we will store the output (fft)
            //    Complex[] fftComplex = new Complex[data.Length]; // the FFT function requires complex format
            //    for (int i = 0; i < data.Length; i++)
            //    {
            //        fftComplex[i] = new Complex(data[i], 0.0); // make it complex format (imaginary = 0)
            //    }
            //    Accord.Math.FourierTransform.FFT(fftComplex, Accord.Math.FourierTransform.Direction.Forward);
            //    for (int i = 0; i < data.Length; i++)
            //    {
            //        fft[i] = fftComplex[i].Magnitude; // back to double
            //        //fft[i] = Math.Log10(fft[i]); // convert to dB
            //    }
            //    return fft;
            //    //todo: this could be much faster by reusing variables
            //}



            public void chart1_Click(object sender, EventArgs e) { }

        }
    }

これは私が修正した元のコードであり、余分なビット (コメント アウト) なしで正常に動作するようになりました。

    Imports NAudio
    Imports NAudio.CoreAudioApi

    Public Class Form1

        Public WithEvents wi As New NAudio.Wave.WaveIn() 'Wave 'in Stream Generates 'by Naudio
        Public WaveFormat As New NAudio.Wave.WaveFormat(44100, 1) 'Wave In format
        'AddHandler wi.DataAvailable, AddressOf StreamWavein_DataAvailable
        Public bwp As New NAudio.Wave.BufferedWaveProvider(wi.WaveFormat)

        'Public wi As NAudio.Wave.WaveIn()
        'Public bwp

        Public Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

            'Dim wi As New NAudio.Wave.WaveIn()
            'wi.DeviceNumber = 0
            'Dim waveforamt As New NAudio.Wave.WaveFormat(44100, 1)
            ''wi.DataAvailable += New EventHandler < WaveInEventArgs > (wi_DataAvailable)\
            'AddHandler wi.DataAvailable, AddressOf StreamWavein_DataAvailable
            'Dim bwp As New NAudio.Wave.BufferedWaveProvider(wi.WaveFormat)

            bwp.BufferLength = ((Math.Pow(2, 13)) * 2)
            bwp.DiscardOnBufferOverflow = True
            wi.StartRecording()


            Chart1.ChartAreas(0).AxisX.Maximum = 400
            Chart1.ChartAreas(0).AxisX.Minimum = 0
        End Sub


        Public Sub StreamWavein_DataAvailable(ByVal sender As Object, ByVal e As NAudio.Wave.WaveInEventArgs) Handles wi.DataAvailable
            bwp.AddSamples(e.Buffer, 0, e.BytesRecorded)
        End Sub



        Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
            Dim frameSize As Integer
            frameSize = Math.Pow(2, 13)
            Dim frames(frameSize) As Byte
            bwp.Read(frames, 0, frameSize)
            If frames.Length = 0 Then
                Return
            End If
            If frames(frameSize - 2) = 0 Then
                Label1.Text = "removed"
                Return
            Else
                Label1.Text = "graphing"
            End If

            Dim SAMPLE_RESOLUTION As Integer
            SAMPLE_RESOLUTION = 16
            Dim BYTES_PER_POINT As Integer
            BYTES_PER_POINT = SAMPLE_RESOLUTION / 8
            Dim vals(frames.Length / BYTES_PER_POINT) As Int32
            Dim Ys(frames.Length / BYTES_PER_POINT) As Double
            Dim Xs(frames.Length / BYTES_PER_POINT) As Double

            Dim i As Integer
            For i = 0 To vals.Length Step 1
                Dim hbyte As Byte
                Dim lbyte As Byte
                hbyte = frames(i * 2 + 1)
                lbyte = frames(i * 2 + 0)
                vals(i) = CInt(CShort((hbyte << 8) Or lbyte))
                Xs(i) = i
                Ys(i) = vals(i)
            Next

            Chart1.Series("Series1").Points.DataBindXY(Xs, Ys)

        End Sub
    End Class

どこが間違っていたのかわかりませんが、どんな助けでも大歓迎です。

4

0 に答える 0