This project has moved. For the latest updates, please go here.

WaveIn using MuLawFormat - is it possible?

Mar 2, 2010 at 6:09 PM

Hello all!

I'm wondering - is it possible to set the WaveFormat of the WaveIn object as MuLawFormat?

In case of

            waveIn.WaveFormat = new WaveFormat(8000, 16, 1);

there is an exception:

           NAudio.MmException: WaveBadFormat calling waveInOpen
            at NAudio.MmException.Try(MmResult result, String function)
            at NAudio.Wave.WaveIn.OpenWaveInDevice()
            at NAudio.Wave.WaveIn.StartRecording()

Thanks in advance!

Coordinator
Mar 2, 2010 at 8:54 PM

Hi there, I don't think you can record directly in mu-law (by the way, that isn't a mu-law wave format anyway - it is 8 bit PCM, you need to explicitly set the format tag). But you can use NAudio to convert to mu-law using the ACM codecs (see the WaveFormatConversionStream).

Mark

Mar 3, 2010 at 11:27 AM

Hi, Mark!

Thanks for the answer!

I'm sorry, I miscopied the line, my bad...

This method is throwing exception:

waveIn.WaveFormat = WaveFormat.CreateMuLawFormat(8000, 1);

And this works fine:

 waveIn.WaveFormat = new WaveFormat(8000, 16, 1);

If I understand you right, I have to create WaveFormat (like "new WaveFormat(8000, 16, 1)"), and then, when I get all the needed audio data from DataAvailable event handler, I can convert received simple PCM stream to mu-law using WaveFormatConversionStream. Is that right?

Coordinator
Mar 3, 2010 at 11:29 AM

Yes, record with 16 bit PCM, then run the audio data you have created through a WaveFormatConversionStream afterwards.

Mark

 

Mar 3, 2010 at 6:23 PM

The theory is good, but the practice is always worse :)... Mark, I have a problem, could you please help me :)...

Here is my code:

using (MemoryStream audioMemoryStream = new MemoryStream(audio))  //audio - array of bytes, raw PCM data
{
    using (PCMStream tempPCMstream = new PCMStream(audioMemoryStream, new WaveFormat(8000, 16, 1))) //PCMStream - my class, I'm using if for playin raw PCM files and it's seemed to be working ok
    {
         using (WaveStream convertedStream = new WaveFormatConversionStream(WaveFormat.CreateMuLawFormat(8000, 1), PCMstream)) //here, as I'm thinkin, I'm conveting stream from one format to another
         {
                   //finalStream.Write(audio, 0, audio.Length); //if I uncomment that string, and write to stream still unconverted data, then I can play it, using WaveFormat(8000, 1). But I need 8-bit mu-law format
                   convertedStream.Read(audio, 0, audio.Length);//here I'm thinking that I get the converted data - in mu-law format, 8000KHz, 1 channel and 8-bit 
                    finalStream.Write(audio, 0, audio.Length);   //but, if I try to play that stream, I'll only hear the terrible noise. I tried all formats: 8-bit, 16-bit, of course mu-law, even tried play it with the CoolEdit, using all its compression formats - no luck
         }
    }
}

Also I have to mention, that when reading bytes from convertedStream, convertedStream.Position is double less than audio.Length. If audio.Length is 160 bytes, then position of convertedStream after reading will move only to 80 bytes. But I think that's because of audio data from microphone is 16-bit, so it takes 2 bytes to store it, but after conversion to mu-law format only 1 byte is required (maybe I'm mistaken)...

Please, can you tell me what I'm missing here, what I'm doing wrong?

Mar 8, 2010 at 12:00 PM

O Mark, where art thou? :)

Coordinator
Mar 11, 2010 at 3:08 PM

hi AT1, sorry, been very busy. I would suggest you first try to save your memory stream to a PCM WAV file and then check that that plays correctly. If your PCM stream is wrong, your converted stream will be too.

Then write some code to convert the PCM WAV stream to a mu law WAV file and see if that plays correctly.

Mark

Mar 31, 2010 at 4:33 PM

This is in VB but it may help Tested as working when the Wav File specified in Filename is 16bit, 8KHz sample rate, mono and PCM. This is the source file ( Dim RecordingFormat As New WaveFormat(8000, 16, 1)  for the source file when I grab it)

 

Dim stream As WaveStream = New WaveFileReader(OutputFilename)
        Dim TargetFormat As WaveFormat
        TargetFormat = WaveFormat.CreateMuLawFormat(8000, 1)

 

 

Dim FileName as String="c:\some_path\some_wav_file_to_convert.wav"

Dim stream As WaveStream = New WaveFileReader(Filename)

        Dim TargetFormat As WaveFormat

        TargetFormat = WaveFormat.CreateMuLawFormat(8000, 1)

	Using ConvertedStream As WaveStream = New WaveFormatConversionStream(TargetFormat, stream)
            WaveFileWriter.CreateWaveFile("C:\Some_path\MuLawfile.wav", ConvertedStream)
        End Using

 

 


Coordinator
Mar 31, 2010 at 4:36 PM

thanks for the code sample thepfy, that's exactly how to do it

Mark