1
votes

I am currently using Naudio to record the user's voice and convert it to a byte array so that i can apply FFT onto it and convert it to a double array and then to a spectrogram. Im currently stuck at converting the WAV file to byte array.Thanks.

  private void mic_Click(object sender, EventArgs e)
    {

        if (MicB.Text.Equals("Start"))
        {
            int deviceNumber = 0;
            sourceStream = new NAudio.Wave.WaveIn();
            sourceStream.DeviceNumber = deviceNumber;
            sourceStream.WaveFormat = new NAudio.Wave.WaveFormat(44100, NAudio.Wave.WaveIn.GetCapabilities(deviceNumber).Channels);
            sourceStream.DataAvailable += new EventHandler<NAudio.Wave.WaveInEventArgs>(sourceStream_DataAvailable);             
            waveWriter = new NAudio.Wave.WaveFileWriter(test.wav, sourceStream.WaveFormat);

            sourceStream.StartRecording();
            MicB.Text = "Stop";
        }

        else if (MicB.Text.Equals("Stop"))
        {               
            if (waveOut != null)
            {
                waveOut.Stop();
                waveOut.Dispose();
                waveOut = null;
            }
            if (sourceStream != null)
            {
                sourceStream.StopRecording();
                sourceStream.Dispose();
                sourceStream = null;
            }
            if (waveWriter != null)
            {
                waveWriter.Dispose();
                waveWriter = null;
            }
            MicB.Text = "Start";
        }
    }

    private void sourceStream_DataAvailable(object sender, NAudio.Wave.WaveInEventArgs e)
    {
        if (waveWriter == null) return;
        waveWriter.Write(e.Buffer, 0, e.BytesRecorded);
        waveWriter.Flush();                    
    }

Edit: i got this code from Coding4Fun and edited a tiny bit but isnt sure if this is what i am looking for which is to convert to float and applying FFT onto it. Sorry i am totally new to audio signalling.

 private void spectro_Click(object sender, EventArgs e)
    {
        //convert to float
        using (WaveFileReader reader = new WaveFileReader(test.wav))
        {

            IWaveProvider stream32 = new Wave16ToFloatProvider(reader);

            using (WaveFileWriter converted = new WaveFileWriter(temp.wav, stream32.WaveFormat))
            {
                byte[] buffer = new byte[8192];
                int bytesRead;
                do
                {
                    bytesRead = stream32.Read(buffer, 0, buffer.Length);
                    converted.Write(buffer, 0, bytesRead);
                } while (bytesRead != 0 && converted.Length < reader.Length);
            }
        }
    }

Question : How do i apply FFT after doing this converting to floating point?

1
Could you just change the sourceStream_DataAvailable event handler to write e.Buffer to a MemoryStream and then use .ToByteArray() on the stream when the recording is stopped?wgraham
the audio recorded already comes in as a byte array. Also, you'd perform FFT on floating point samples, so the task would be to convert each 16 bit sample into a 32 bit floating point before passing it on to the FFT.Mark Heath
Thanks Graham will try that.Derrick Peh
Is it right to use the Wave16toFloatProvider class? how would i implement it to convert each 16bit sample to Floating Point?Derrick Peh

1 Answers

0
votes

This is difficult to answer, but I can venture a guess. You're using a WaveFileWriter. Does a WaveStreamWriter exist in the library? In that case, you can provide a MemoryStream as the parameter and use the ToArray on the stream to get the bytes.