Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to write wav byte array to response using Microsoft Speech Object Library?

I am attempting to convert text to audio in C# using the Microsoft Speech Object Library. I have successfully done this when saving the audio directly to a wav file however my main goal is to save the audio to a byte array which I can then write out to the response in asp.net (so the end user can have it downloaded on their machine).

When I attempt to open the wav file written out to the response that gets downloaded nothing plays and an error is stated how windows media player cannot open the file.

The code below shows what I have working and what does not.

Anyone have any ideas of what I may be missing in the second part when just trying to write the byte array out to the response as a wav?

        ////////////////////////////////////////////////
        // THIS WORKS
        //SpVoice my_Voice = new SpVoice();                   //declaring and initializing SpVoice Class
        //SpeechVoiceSpeakFlags my_Spflag = SpeechVoiceSpeakFlags.SVSFlagsAsync; // declaring and initializing Speech Voice Flags

        //SpFileStream spFileStream = new SpFileStream();     //declaring and Initializing fileStream obj
        //SpeechStreamFileMode spFileMode = SpeechStreamFileMode.SSFMCreateForWrite;  //declaring fileStreamMode as to Create or Write
        //spFileStream.Open("C:\\temp\\hellosample.wav", spFileMode, false);
        //my_Voice.AudioOutputStream = spFileStream;
        //my_Voice.Speak("test text to audio in asp.net", my_Spflag);
        //my_Voice.WaitUntilDone(-1);
        //spFileStream.Close();
        ////////////////////////////////////////////////

        ////////////////////////////////////////////////
        // THIS DOES NOT WORK
        SpVoice my_Voice = new SpVoice();                   //declaring and initializing SpVoice Class
        SpeechVoiceSpeakFlags my_Spflag = SpeechVoiceSpeakFlags.SVSFlagsAsync; // declaring and initializing Speech Voice Flags

        SpMemoryStream spMemStream = new SpMemoryStream();
        spMemStream.Format.Type = SpeechAudioFormatType.SAFT11kHz8BitMono;
        object buf = new object();
        my_Voice.AudioOutputStream = spMemStream;
        my_Voice.Speak("test text to audio!", my_Spflag);
        my_Voice.WaitUntilDone(-1);
        spMemStream.Seek(0, SpeechStreamSeekPositionType.SSSPTRelativeToStart);
        buf = spMemStream.GetData();
        byte[] byteArray = (byte[])buf;
        Response.Clear();
        Response.ContentType = "audio/wav";
        Response.AppendHeader("Content-Disposition", "attachment; filename=mergedoutput.wav");
        Response.BinaryWrite(byteArray);
        Response.Flush();
        ////////////////////////////////////////////////
like image 498
Al Belmondo Avatar asked Mar 04 '14 22:03

Al Belmondo


2 Answers

I would like to recommend that you use the SpeechSynthesizer class in the System.Speech assembly instead of Microsoft Speech Object Library, because the assembly is included in .NET libraries.

I post an example below, to explain how to solve your problem using the SpeechSynthesizer class, which is made on ASP.NET MVC. I hope this resolves your issue.

public class HomeController : Controller
{
    public async Task<ActionResult> Index()
    {
        Task<FileContentResult> task = Task.Run(() =>
        {
            using (var synth = new SpeechSynthesizer())
            using (var stream = new MemoryStream())
            {
                synth.SetOutputToWaveStream(stream);
                synth.Speak("test text to audio!");
                byte[] bytes = stream.GetBuffer();
                return File(bytes, "audio/x-wav");
            }
        });

        return await task;
    }
}
like image 71
Jin-Wook Chung Avatar answered Oct 10 '22 12:10

Jin-Wook Chung


I ended up using the microsoft translator service and this .net lib (http://translatorservice.codeplex.com/) to connect to it. Works great. Code below:

        // Connect to translator service
        SpeechSynthesizer speech = new SpeechSynthesizer("clientID", "secretKey");
        speech.AudioFormat = SpeakStreamFormat.MP3;
        speechStream = speech.GetSpeakStream(text, language);

        // Write it out to the stream
        Response.Clear();
        Response.ContentType = "audio/mp3";
        Response.AppendHeader("Content-Disposition", "attachment; filename=" + fileName + "");
        speechStream.CopyTo(Response.OutputStream);
        Response.Flush();
like image 2
Al Belmondo Avatar answered Oct 10 '22 14:10

Al Belmondo