Download wav stream

2.1k views Asked by At

I am developing a voice recognition software and one of the requirements for the voice recognition engine is a wave stream. The function is recognition engine.setInputToWaveStream(Stream audioSource)

So I have started looking into how to get a a wave file from a webpage using memorystream. This is my current code.

using (WebClient webClient = new WebClient())
{
    byte[] data = webClient.DownloadData(@"http://192.0.2.82:6180/audio.wav");

    using (MemoryStream mem = new MemoryStream(data))
    {
        recEngine.SetInputToWaveStream(mem);
    }
} 

This is not working so could someone please point me to the right direction. I have tried looking at other resources but most of them are outdated and the NAudio library solutions are not working for me.

2

There are 2 answers

2
Dan O'Boyle On BEST ANSWER

It looks like you're passing the data into the MemoryStream where the size of the stream should be declared.
From the docs on MemoryStream()

Initializes a new instance of the MemoryStream class with an expandable capacity initialized to zero.

Try something like this:

using (WebClient webClient = new WebClient())
{
  byte[] data = webClient.DownloadData(@"http://192.0.2.82:6180/audio.wav");

  using (MemoryStream mem = new MemoryStream())
  {
    mem.Write(data, 0 , data.Length);
    recEngine.SetInputToWaveStream(mem);
  }
}

Depending on the format of your .wav data you could also use mem.WriteByte

0
Zod On

Its been a while and after messing around a lot, I have succeeded in doing what this question asks but failed to integrate it into my system as there is a latency. Maybe in the future I'll be able to get rid of this latency. For the purpose of this question I'll post my solution so other people might be helped. :)

I tried a lot in C# to record the audio stream but the key problem was that in c# if you do not know the length of what you're recording it gets stuck in a infinite loop recording forever. Tried other methods to cut this loop but didn't work. So I moved to java to see if it can do what I need. Here I succeeded and I'll post the java code below.

public class first {

    public static int samplingTime = 5;         //sampling time of 5 seconds

    public static void main(String[]args){

         try{
                URLConnection conn = new URL("http://120.49.54.128:4040/audio.wav").openConnection();
                InputStream is = conn.getInputStream();

                OutputStream outstream = new FileOutputStream(new File("C:/Fraps/output.wav"));
                byte[] buffer = new byte[4096];
                int len;
                long t = System.currentTimeMillis();
                while ((len = is.read(buffer)) > 0 && System.currentTimeMillis() - t <= (samplingTime*1000)) {
                    outstream.write(buffer, 0, len);
                }
                outstream.close();
            }
            catch(Exception e){
                System.out.print(e);
            }


    }



}

What this script achieves is that it opens a connection to the continuous audio stream and then saves the audio every 5 seconds. It rewrites the current audio file every 5 seconds so you always have the most recent 5 second of the audio stream. You can save this java program as a runnable jar (exe) and then use this c# code to run it whenever you need to sample the audio stream.

Process Saveprocess = new Process();
                        Saveprocess.StartInfo.FileName = "c:\\Fraps\\saveAudioStream.jar";                      //this is the runnable jar file that you made from the java program
                        Saveprocess.Start();
                        Saveprocess.WaitForExit();  

And voila you have a wav file on your hard risk that you can feed it into whatever you need. There is another problem though because the length of this wave file is kind of messed up and some classes cannot use it. To counter that you can use an external library called NAudio, add the NAudio.dll to your c# project reference and then use this code snippet.

private void fixWaveFile(String inputPath, String outputPath)
        {
            using (var reader = new WaveFileReader(inputPath))
            using (var converter = WaveFormatConversionStream.CreatePcmStream(reader))
            {
                WaveFileWriter.CreateWaveFile(outputPath, converter);
            }

        } 

That should fix the length problem. As you can see a lot of work and hope it helps someone!