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

AcmNotPossible calling acmStreamOpen

Feb 26, 2009 at 9:42 AM
I am trying to create a small program that takes a given WAV file and converts it to a compressed ADPCM WAV. I have got the code working with the GetTargetFormat prompt but when i try to crearte my own WaveFormat it causes an "AcmNotPossible calling acmStreamOpen" error. My code is posted below:

            using (WaveFileReader reader = new WaveFileReader(txtIName.Text))
            {
               //Set encoding settings using prompt
                WaveFormat targetFormat = GetTargetFormat(reader.WaveFormat);
                //Set encoding settings programatically
                //WaveFormat targetFormat = WaveFormat.CreateCustomFormat(WaveFormatEncoding.DigiAdpcm, 8000, 1, 4055, 256, 4);

                //Convert to new format
                using (WaveStream convertedStream = new WaveFormatConversionStream(targetFormat, reader))
                {
                    WaveFileWriter.CreateWaveFile(txtOName.Text, convertedStream);
                }
             }

Any help will be greatly appreciated.
Feb 26, 2009 at 2:09 PM
Depending upon what the target format is and your input is, you may need to use multiple WaveFormatConversionStreams in order to perform the conversion within multiple steps. Also, I noticed that the WaveFormatConversionStreamTests use an AdpcmWaveFormat constructor.
Feb 26, 2009 at 2:23 PM

The input is a PCM 16bit signed 8000Hz 128kpbs mono WAV and I want to convert to an IMA ADPCM 8000Hz 4bit mono WAV. As I said earlier if I use the prompt to set the settings it works fine, it only gives the error if I try and set the settings in the code using the WaveFormat static method (this is demonstrated in the code exert I included) so I don’t think I will have to use multiple streams.

Thanks for your help.

From: geiman [mailto:notifications@codeplex.com]
Sent: Friday, 27 February 2009 1:10 AM
To: Scott Edwards
Subject: Re: AcmNotPossible calling acmStreamOpen [naudio:48587]

From: geiman

Depending upon what the target format is and your input is, you may need to use multiple WaveFormatConversionStreams in order to perform the conversion within multiple steps. Also, I noticed that the WaveFormatConversionStreamTests use an AdpcmWaveFormat constructor.

Read the full discussion online.

To add a post to this discussion, reply to this email (naudio@discussions.codeplex.com)

To start a new discussion for this project, email naudio@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com

Coordinator
Feb 26, 2009 at 4:53 PM
WaveFormat.CreateCustomFormat only works if the format in question doesn't have any extra bytes beyond the WAVEFORMAT structure. So you may have to create your own class derived from WaveFormat, in the same way that AdpcmWaveFormat does. These things are a real pain to figure out, but at least you could inspect the WaveFormat created by the NAudioDemo app to see what ought to be in there.

Mark


Feb 26, 2009 at 5:06 PM

Are you saying create a class that inherits WaveFormat so that I can create a method and actually set ExtraSize? I did notice that I wasn’t able to set this but the WaveFormat that is created by the prompt has this set to 2. The only issue that I have with this is that I actaully captured the WaveFormat object created by the prompt and then wrote that to a binary file so that I could then read it back at a later time to get around not being able to set ExtraSize and to ensure there wasn’t anything else being set that I wasn’t aware of. This worked in the fact that i now had a WaveFormat with ExtraSize set to 2 (loaded from the binary file) but unfortuantely it still threw the error.

Sorry if I miss understood what you were saying.

From: markheath [mailto:notifications@codeplex.com]
Sent: Friday, 27 February 2009 3:53 AM
To: Scott Edwards
Subject: Re: AcmNotPossible calling acmStreamOpen [naudio:48587]

From: markheath

WaveFormat.CreateCustomFormat only works if the format in question doesn't have any extra bytes beyond the WAVEFORMAT structure. So you may have to create your own class derived from WaveFormat, in the same way that AdpcmWaveFormat does. These things are a real pain to figure out, but at least you could inspect the WaveFormat created by the NAudioDemo app to see what ought to be in there.

Mark

Read the full discussion online.

To add a post to this discussion, reply to this email (naudio@discussions.codeplex.com)

To start a new discussion for this project, email naudio@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com

Coordinator
Feb 26, 2009 at 6:00 PM
Yes, but you not only need to set ExtraSize, you need to fill in the data that makes up that extra size. If it is two, then in your derived class add an Int16 for the extra data, and set it to the appropriate values in its constructor.
Feb 27, 2009 at 4:23 AM

I have tried that but it doesn’t seem to accept my child class when I try and pass it to WaveFormatConversionStream it won’t accept it because it isn’t of type WaveFormat (even though it should through Polymorphism) and I have tried casting and all sorts of things and it just errors saying it can’t convert MyWaveFormat to WaveFormat.

From: markheath [mailto:notifications@codeplex.com]
Sent: Friday, 27 February 2009 5:00 AM
To: Scott Edwards
Subject: Re: AcmNotPossible calling acmStreamOpen [naudio:48587]

From: markheath

Yes, but you not only need to set ExtraSize, you need to fill in the data that makes up that extra size. If it is two, then in your derived class add an Int16 for the extra data, and set it to the appropriate values in its constructor.

Read the full discussion online.

To add a post to this discussion, reply to this email (naudio@discussions.codeplex.com)

To start a new discussion for this project, email naudio@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com

Coordinator
Mar 2, 2009 at 12:27 PM
I'm not sure why that would happen. Can you share your code for your derived WaveFormat class?
Mar 3, 2009 at 6:31 AM
Here is the code for the class:
       
private class MyWaveFormat:WaveFormat
        {
            public MyWaveFormat(WaveFormatEncoding WaveFormatTag, short BitsPerSample, short Channels, int AverageBytesPerSecond, short BlockAlign, int SampleRate, short ExtraSize)
            {
                base.extraSize = ExtraSize;
                base.averageBytesPerSecond = AverageBytesPerSecond;
                base.bitsPerSample = BitsPerSample;
                base.blockAlign = BlockAlign;
                base.channels = Channels;
                base.sampleRate = SampleRate;
                base.waveFormatTag = WaveFormatTag;
            }
}

I then changed the code as follows:

using (WaveFileReader reader = new WaveFileReader(txtIName.Text))
            {
                MyWaveFormat targetFormat = new MyWaveFormat(WaveFormatEncoding.DigiAdpcm, 8000, 1, 4055, 256, 4, 2);

                //Convert to new format
                using (WaveStream convertedStream = new WaveFormatConversionStream(targetFormat, reader))
                {
                    WaveFileWriter.CreateWaveFile(txtOName.Text, convertedStream);
                }
            }

There is no issues detected but when i run the program i get the following error "Type 'WAV_Encoding_Test.Form1+MyWaveFormat' cannot be marshaled as an unmanaged structure; no meaningful size or offset can be computed."
Coordinator
Mar 3, 2009 at 12:47 PM
That's a strange one. Can you try the following
1. Make your class public
2. Move it out of Form1 (no longer a nested class)
3. Add a private member of type short (to store your "extra" 2 bytes)

Mark
Mar 4, 2009 at 3:34 AM

Could you clarify step three for me?

From: markheath [mailto:notifications@codeplex.com]
Sent: Tuesday, 3 March 2009 11:48 PM
To: Scott Edwards
Subject: Re: AcmNotPossible calling acmStreamOpen [naudio:48587]

From: markheath

That's a strange one. Can you try the following
1. Make your class public
2. Move it out of Form1 (no longer a nested class)
3. Add a private member of type short (to store your "extra" 2 bytes)

Mark

Read the full discussion online.

To add a post to this discussion, reply to this email (naudio@discussions.codeplex.com)

To start a new discussion for this project, email naudio@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com

Coordinator
Mar 4, 2009 at 9:31 AM
Simply add a short in there. Extra size means how many extra bytes there are on top of the original WaveFormat structure. You need a variable to hold that data (a short because you have two extra bytes). And you should also set the contents of that extra data according to the specification of the specific WaveFormatTag you are using

private class MyWaveFormat:WaveFormat
        {
            short extraData;

            public MyWaveFormat(WaveFormatEncoding WaveFormatTag, short BitsPerSample, short Channels, int AverageBytesPerSecond, short BlockAlign, int SampleRate, short ExtraSize)
            {
                base.extraSize = ExtraSize;
                base.averageBytesPerSecond = AverageBytesPerSecond;
                base.bitsPerSample = BitsPerSample;
                base.blockAlign = BlockAlign;
                base.channels = Channels;
                base.sampleRate = SampleRate;
                base.waveFormatTag = WaveFormatTag;
            }
}
Mar 4, 2009 at 11:54 AM

Sorry I should have been more specific I was asking how I was to set the extraData variable. Do I just read the first two bytes of the file into it?


From: markheath [mailto:notifications@codeplex.com]
Sent: Wednesday, 4 March 2009 8:31 PM
To: Scott Edwards
Subject: Re: AcmNotPossible calling acmStreamOpen [naudio:48587]

From: markheath

Simply add a short in there. Extra size means how many extra bytes there are on top of the original WaveFormat structure. You need a variable to hold that data (a short because you have two extra bytes). And you should also set the contents of that extra data according to the specification of the specific WaveFormatTag you are using

private class MyWaveFormat:WaveFormat
{
short extraData;

public MyWaveFormat(WaveFormatEncoding WaveFormatTag, short BitsPerSample, short Channels, int AverageBytesPerSecond, short BlockAlign, int SampleRate, short ExtraSize)
{
base.extraSize = ExtraSize;
base.averageBytesPerSecond = AverageBytesPerSecond;
base.bitsPerSample = BitsPerSample;
base.blockAlign = BlockAlign;
base.channels = Channels;
base.sampleRate = SampleRate;
base.waveFormatTag = WaveFormatTag;
}
}

Read the full discussion online.

To add a post to this discussion, reply to this email (naudio@discussions.codeplex.com)

To start a new discussion for this project, email naudio@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com

Coordinator
Mar 6, 2009 at 12:33 PM
the 2 extra bytes likely contain configuration flags / values for the decoder. What they should contain depends entirely on what compression format you are using
Mar 16, 2009 at 2:28 AM

The original file is PCM and I am converting to ADPCM. So what will I be required to do?

From: markheath [mailto:notifications@codeplex.com]
Sent: Friday, 6 March 2009 11:33 PM
To: Scott Edwards
Subject: Re: AcmNotPossible calling acmStreamOpen [naudio:48587]

From: markheath

the 2 extra bytes likely contain configuration flags / values for the decoder. What they should contain depends entirely on what compression format you are using

Read the full discussion online.

To add a post to this discussion, reply to this email (naudio@discussions.codeplex.com)

To start a new discussion for this project, email naudio@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com

Coordinator
Mar 24, 2009 at 10:44 AM
Use the NAudioDemo app to do a conversion, and debug it to see what the values of those two extra bytes are.