Skip to content

Instantly share code, notes, and snippets.

@neo125874
Last active September 22, 2016 02:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save neo125874/e656d74acb787ac11c5cddea32b80b3e to your computer and use it in GitHub Desktop.
Save neo125874/e656d74acb787ac11c5cddea32b80b3e to your computer and use it in GitHub Desktop.
PlayOnServer(controller)
//exclude the special character
[ValidateInput(false)]
public FileResult TextToMp3(string text)
{
//Primary memory stream for storing mp3 audio
var mp3Stream = new MemoryStream();
//Speech format
var speechAudioFormatConfig = new SpeechAudioFormatInfo(samplesPerSecond: 8000, bitsPerSample: AudioBitsPerSample.Sixteen, channel: AudioChannel.Stereo);
//Naudio's wave format used for mp3 conversion. Mirror configuration of speech config.
var waveFormat = new WaveFormat(speechAudioFormatConfig.SamplesPerSecond, speechAudioFormatConfig.BitsPerSample, speechAudioFormatConfig.ChannelCount);
try
{
//Build a voice prompt to have the voice talk slower and with an emphasis on words
var prompt = new PromptBuilder { Culture = CultureInfo.CreateSpecificCulture("zh-TW") };
prompt.StartVoice(prompt.Culture);
prompt.StartSentence();
prompt.StartStyle(new PromptStyle() { Emphasis = PromptEmphasis.Reduced, Rate = PromptRate.Slow });
prompt.AppendText(text);
prompt.EndStyle();
prompt.EndSentence();
prompt.EndVoice();
//Wav stream output of converted text to speech
using (var synthWavMs = new MemoryStream())
{
//Spin off a new thread that's safe for an ASP.NET application pool.
var resetEvent = new ManualResetEvent(false);
ThreadPool.QueueUserWorkItem(arg =>
{
try
{
//initialize a voice with standard settings
var siteSpeechSynth = new SpeechSynthesizer();
siteSpeechSynth.SelectVoice("Microsoft Server Speech Text to Speech Voice (zh-TW, HanHan)");
siteSpeechSynth.Volume = 100;
siteSpeechSynth.Rate = 2;
//Set memory stream and audio format to speech synthesizer
siteSpeechSynth.SetOutputToAudioStream(synthWavMs, speechAudioFormatConfig);
//build a speech prompt
siteSpeechSynth.Speak(prompt);
}
catch (Exception ex)
{
//This is here to diagnostic any issues with the conversion process. It can be removed after testing.
Response.AddHeader("EXCEPTION", ex.GetBaseException().ToString());
}
finally
{
resetEvent.Set();//end of thread
}
});
//Wait until thread catches up with us
WaitHandle.WaitAll(new WaitHandle[] { resetEvent });
//Estimated bitrate
var bitRate = (speechAudioFormatConfig.AverageBytesPerSecond * 8);
//Set at starting position
synthWavMs.Position = 0;
//Be sure to have a bin folder with lame dll files in there. They also need to be loaded on application start up via Global.asax file
using (var mp3FileWriter = new LameMP3FileWriter(outStream: mp3Stream, format: waveFormat, bitRate: bitRate)) synthWavMs.CopyTo(mp3FileWriter);
}
}
catch (Exception ex)
{
Response.AddHeader("EXCEPTION", ex.GetBaseException().ToString());
}
finally
{
//Set no cache on this file
Response.Cache.SetExpires(DateTime.UtcNow.AddMinutes(-1));
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.Cache.SetNoStore();
//required for chrome and safari
Response.AppendHeader("Accept-Ranges", "bytes");
//Write the byte length of mp3 to the client
Response.AddHeader("Content-Length", mp3Stream.Length.ToString(CultureInfo.InvariantCulture));
}
//return the converted wav to mp3 stream to a byte array for a file download
return File(mp3Stream.ToArray(), "audio/mp3");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment