This project has moved and is read-only. For the latest updates, please go here.

Ima Adpcm to PCM

Feb 18, 2013 at 1:15 AM

I am trying to convert an Ima Adpcm stream into a PCM stream.
My latest attempt looks as follows:
            var bytes = File.ReadAllBytes(@"c:\temp\bytes.bin");
            using (var stream = new MemoryStream(bytes))
                RawSourceWaveStream rawStream = new RawSourceWaveStream(stream, new ImaAdpcmWaveFormat(8000, 1, 4));
                WaveFormatConversionStream convertStream = new WaveFormatConversionStream(new WaveFormat(8000, 16, 1), rawStream);
                var buffer = new byte[640];
                convertStream.Read(buffer, 0, buffer.Length);
This implementations has two problems:
  1. The WaveFormatConversionStream is trying to create an AcmStream internally and its Ctor throws a DivisionByZero exception because the ImaAdpcm BlockAlign value is zero.
  2. If I fix that, I get "AcmNotPossible calling acmStreamOpen" from the acmStreamOpen call.
When I enumerate the codec on my machine I see this:
Long Name: Microsoft IMA ADPCM CODEC
Short Name: Microsoft IMA ADPCM
Driver ID: 5370400
   Format 0: 8.000 kHz, 4 Bit, Mono
      FormatTag: DviAdpcm, Support Flags: Codec
      WaveFormat: DviAdpcm 8000Hz Channels: 1 Bits: 4 Block Align: 256, AverageBytesPerSecond: 4055 (32.4 kbps), Extra Size: 2
      Extra Bytes:
      F9 01 
I tried setting the BlockAlign to be 256 and the AvgBPS to 4055 (because the default ImaAdpcm set them to zero) and I still get the same error.

How can I convert my stream into PCM?

Thank you,
Feb 18, 2013 at 10:04 AM
the ImaAdpcmWaveFormat class was never finished. Needs to have everything set up correctly. Probably it is just the samples per block you need to set up (505 I think)
Feb 18, 2013 at 5:49 PM
I tried filling out the missing parts in a debugger, but acmStreamOpen still fails.
Is there a way to debug this call (maybe enable tracing)?
I used exactly the values as they appear above in the driver format details and it still gave me the same error.
Feb 18, 2013 at 6:45 PM
only thing left to try is to use WaveFormatConversionStream.ConvertToPcm. That uses acmFormatSuggest to let the codec suggest a PCM format it can decode to (although your PCM format looks right to me). If that doesn't work, then the either codec is lying about what waveformat it accepts, or you still haven't got something right. Did you set up samplesPerBlock?
Feb 18, 2013 at 6:49 PM
I actually called AcmStream.SuggestPcmFormat and it gave me the same error.
Yes, I've set the samplesPerBlock and the blockAlign and the AvgBytesPerSec...
Is there anything else I can try?
Feb 18, 2013 at 6:56 PM
you need to view the bytes in a hex editor. Create an instance of the ImaWavbeFormat, copy it into a byte array (I think Buffer.BlockCopy can do this), and then byte by byte check it is identical to the WaveFormat returned by the ACM.