Search code examples
c#asp.netaudionaudio

change format from wav to mp3 in memory stream in NAudio


Hi there iam trying to convert text to speech (wav) in the memorystream convert it to mp3 and then play it on the users page.so need i help what to do next?

here is my asmx code :

[WebMethod]
public byte[] StartSpeak(string Word)
{
    MemoryStream ms = new MemoryStream();
    using (System.Speech.Synthesis.SpeechSynthesizer synhesizer = new System.Speech.Synthesis.SpeechSynthesizer())
    {
        synhesizer.SelectVoiceByHints(System.Speech.Synthesis.VoiceGender.NotSet, System.Speech.Synthesis.VoiceAge.NotSet, 0, new System.Globalization.CultureInfo("en-US"));
        synhesizer.SetOutputToWaveStream(ms);
        synhesizer.Speak(Word);
    }
    return ms.ToArray();

    }

Thanks.


Solution

  • You need an MP3 compressor library. I use Lame via the Yeti Lame wrapper. You can find code and a sample project here.

    Steps to get this working:

    1. Copy the following files from MP3Compressor to your project:

      • AudioWriters.cs
      • Lame.cs
      • Lame_enc.dll
      • Mp3Writer.cs
      • Mp3WriterConfig.cs
      • WaveNative.cs
      • WriterConfig.cs

    2. In the project properties for Lame_enc.dll set the Copy to Output property to Copy if newer or Copy always.

    3. Edit Lame.cs and replace all instances of:

      [DllImport("Lame_enc.dll")]
      

      with:

      [DllImport("Lame_enc.dll", CallingConvention = CallingConvention.Cdecl)]
      
    4. Add the following code to your project:

      public static Byte[] WavToMP3(byte[] wavFile)
      {
           using (MemoryStream source = new MemoryStream(wavFile))
           using (NAudio.Wave.WaveFileReader rdr = new NAudio.Wave.WaveFileReader(source))
           {
               WaveLib.WaveFormat fmt = new WaveLib.WaveFormat(rdr.WaveFormat.SampleRate, rdr.WaveFormat.BitsPerSample, rdr.WaveFormat.Channels);
      
               // convert to MP3 at 96kbit/sec...
               Yeti.Lame.BE_CONFIG conf = new Yeti.Lame.BE_CONFIG(fmt, 96);
      
               // Allocate a 1-second buffer
               int blen = rdr.WaveFormat.AverageBytesPerSecond;
               byte[] buffer = new byte[blen];
      
               // Do conversion
               using (MemoryStream output = new MemoryStream())
               { 
                   Yeti.MMedia.Mp3.Mp3Writer mp3 = new Yeti.MMedia.Mp3.Mp3Writer(output, fmt, conf);
      
                   int readCount;
                   while ((readCount = rdr.Read(buffer, 0, blen)) > 0)
                       mp3.Write(buffer, 0, readCount);
                   mp3.Close();
      
                   return output.ToArray();
               }
           }
       }
      
    5. Either add a reference to System.Windows.Forms to your project (if it's not there already), or edit AudioWriter.cs and WriterConfig.cs to remove the references. Both of these have a using System.Windows.Forms; that you can remove, and WriterConfig.cs has a ConfigControl declaration that needs to be removed/commented out.

    Once all of that is done you should have a functional in-memory wave-file to MP3 converter that you can use to convert the WAV file that you are getting from the SpeechSynthesizer into an MP3.