-1

I'm having trouble getting a good response from wit.ai's speech end point. The response is always 400. I seem to be following the docs but something's wrong.

Any help would be appreciated.

private string ProcessSpeechStream(Stream stream)
  {
            BinaryReader filereader = new BinaryReader(stream);
            byte[] arr = filereader.ReadBytes((Int32)stream.Length);
            filereader.Close();


            HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://api.wit.ai/speech");
            request.SendChunked = true;
            request.Method = "POST";
            request.Headers["Authorization"] = "Bearer " + APIToken;
            request.ContentType  = "chunked"; 
            request.ContentLength = arr.Length;          
            var st = request.GetRequestStream();
            st.Write(arr, 0, arr.Length);
            st.Close();
            // Process the wit.ai response
            try
            {
                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                if (response.StatusCode == HttpStatusCode.OK)
                {
                    StreamReader response_stream = new StreamReader(response.GetResponseStream());
                    return response_stream.ReadToEnd();
                }
                else
                {
                    Logger.AILogger.Log("Error: " + response.StatusCode.ToString());
                    return string.Empty;

                }
            }
            catch (Exception ex)
            {
                Logger.AILogger.Log("Error: " + ex.Message, ex);
                return string.Empty;
            }
  }
Amen Jlili
  • 1,884
  • 4
  • 28
  • 51
  • You should set the `Transfer-encoding` header to `request.Transfer-encoding = "chunked";` and the `ContentType` header to the format and parameters of your wave stream (e.g. `request.ContentType = "audio/mpeg3";`). For `audio/wav`, parameters are mandatory (e.g. `request.ContentType = "audio/wav;encoding=ms-adpcm;bits=32;rate=16k;endian=little";`).. Also, it accepts mono and not stereo. – Jimi Jan 19 '18 at 22:39
  • @Jimi Thanks for the comment! Set the transfer-encoding seems to upset the runtime. It throws an exception with the message: Chunked encoding must be set via the SendChunked property. I think SendChunked property is way to do it using the HTTPRequest class. – Amen Jlili Jan 19 '18 at 22:59
  • I tried what you suggested. Always an exception... @Jimi – Amen Jlili Jan 19 '18 at 23:04
  • Yes, you are right, HttpWebRequest wants the header set with `request.SendChunked = true;` which you already have. Have you set the ContentType? A 400 exception means invalid Body or invalid ContentType. So, the ContentType is not as expected or the audio format is not supported. Can't you read the response text an see what's in there? – Jimi Jan 19 '18 at 23:15
  • The funny thing is that saving the audio to a file works. I honestly don't know what's the problem. – Amen Jlili Jan 19 '18 at 23:32
  • I have set the content type to what you noted earlier on but it didn't work. – Amen Jlili Jan 19 '18 at 23:34
  • What do you mean with _to what you noted earlier_? What is that audio file format? Did you have the chance to read the response? They should send, in case of error, a plain text file with the description of what went wrong. You should probably try it with HttpClient, because HttpWebRequest always raises an exception for status codes over 399. HttpClient doesn't. – Jimi Jan 19 '18 at 23:40
  • This file format I tried audio/wav;encoding=ms-adpcm;bits=32;rate=16k;endian=little – Amen Jlili Jan 19 '18 at 23:42
  • Yes, right, but is that the real file format and encoding? What I wrote was just an example. – Jimi Jan 19 '18 at 23:43
  • I'm using Naudio to record. I'm defining my encoding like this: waveSource.WaveFormat = new WaveFormat(44100, 1); The file's format is wav (for when I'm saving the stream to the disk). – Amen Jlili Jan 19 '18 at 23:45
  • Do you mind if you could post an answer on how to do this with Httpclient? Thanks for your time @Jimi – Amen Jlili Jan 19 '18 at 23:48
  • As I wrote before, wave audio is the most complex to manage, because you have to specify those parameters. If you encode it as .mp3, you just have to specify `ContentType = "audio/mpeg3"`. If it doesn't work, I can see about the HttpClient substitute. – Jimi Jan 19 '18 at 23:52
  • it doesn't work still... – Amen Jlili Jan 20 '18 at 00:09
  • @Jimi thanks for the help i have figured it out! – Amen Jlili Jan 20 '18 at 01:09
  • Well, I'm glad to "hear" it :). Good work then. – Jimi Jan 20 '18 at 01:15
  • @Jimi hey there. My stream seem to have some sort of high noise in the background that I can hear from the console inbox at my wit.ai account. Do you have an idea why would that happen? I've tried replaying the stream using the sound player and also naudio and it plays fine. – Amen Jlili Jan 20 '18 at 03:40
  • I have fixed it – Amen Jlili Jan 20 '18 at 06:16

1 Answers1

1

This code sample uses the correct encoding. If you are using Naudio make sure you waveformat is like the encoding (Plus it has to be mono):

  private string ProcessSpeechStream(Stream stream)
        {

            var ms = new MemoryStream();
            stream.CopyTo(ms);
            var arr = ms.ToArray();
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://api.wit.ai/speech");
            request.SendChunked = true;
            request.Method = "POST";
            request.Headers["Authorization"] = "Bearer " + APIToken;
            request.ContentType = "audio/raw;encoding=signed-integer;bits=16;rate=44100;endian=little";
            request.ContentLength = arr.Length;
            var st = request.GetRequestStream();
            st.Write(arr, 0, arr.Length);
            st.Close();
            // Process the wit.ai response
            try
            {
                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                if (response.StatusCode == HttpStatusCode.OK)
                {
                    StreamReader response_stream = new StreamReader(response.GetResponseStream());
                    return response_stream.ReadToEnd();
                }

            }
            catch (Exception ex)
            {
                // use your own exception handling class
                // Logger.AILogger.Log("Error: " + ex.Message, ex);
                return string.Empty;
            }
        }
Amen Jlili
  • 1,884
  • 4
  • 28
  • 51