VLM

I am writing a program to convert PCM Wav files to other formats like mula, GSM6.1, ADPCM etc.

When I call acmFormatSuggest for the format tag WAVE_FORMAT_GSM610 I get an Not Possible error(512). This codec is installed on my system and I am able to use another program to convert my WAV file to GSM6.10 format. I call the function as follows:

WAVEFORMATEX *srcWavFmt;

GSM610WAVEFORMAT *destWavFmt;

srcWavFmt = (LPWAVEFORMATEX)calloc(2, max_format_size);

srcWavFmt->nAvgBytesPerSec = srcFmt->AverageBytesPerSecond;

srcWavFmt->nBlockAlign = srcFmt->BlockAlign;

srcWavFmt->nChannels = srcFmt->Channels;

srcWavFmt->nSamplesPerSec = srcFmt->SamplesPerSecond;

srcWavFmt->wBitsPerSample = srcFmt->BitsPerSample;

srcWavFmt->wFormatTag = WAVE_FORMAT_PCM;

srcWavFmt->cbSize = 0;

destWavFmt = (LPGSM610WAVEFORMAT)((char*)srcWavFmt+max_format_size);

destWavFmt->wfx.wFormatTag = WAVE_FORMAT_GSM610;

result = acmFormatSuggest(NULL, srcWavFmt, (LPWAVEFORMATEX) destWavFmt, max_format_size, ACM_FORMATSUGGESTF_WFORMATTAG);

I get result = 512.

Any suggestions please!!!

Thanks



Re: Windows SDK ACM: Converting PCM Wave files to another format

Chris P.

In your example what is the actual srcFmt description populated as

Channels:

SamplesPerSecond:

BitsPerSample:

e.g. More than 1 channel may fail, bits per sample other than 16 may fail ...






Re: Windows SDK ACM: Converting PCM Wave files to another format

VLM

Thanks a lot. Changing the channel to 1 for the source format worked.

My next question is what additional information is to be stored in the header for the GSM6.10, MS-ADPCM, IMA-ADPCM format sound files I have tried the following but doesn't work:

1. Store the same header format as for a PCM wave file.

2. Store Samples per block in the fmt chunk of the Header.

What is a fact chunk What should be written to that





Re: Windows SDK ACM: Converting PCM Wave files to another format

Chris P.

You should write the Dest WaveFormatEx struct as is, including the extra data specified by cbSize. So your write size should be sizeof(WAVEFORMATEX) + destWavFmt->cbSize.

The fact chunk is not required but can be useful. It contains the total number of samples written to the file, usually only used with compressed formats.






Re: Windows SDK ACM: Converting PCM Wave files to another format

VLM

I have tried this but it is not working. I guess I am still doing something wrong. This is what I do:

int AudioConverter::WriteGSM610FormatFile(String^ destFileName, BYTE* destBuffer, DWORD nDataLength, LPGSM610WAVEFORMAT inpWaveFormat)

{

System::IO::FileStream ^fs = gcnew System::IO::FileStream(destFileName, System::IO::FileMode::Create);

System::IO::BinaryWriter ^wavBinaryWriter = gcnew System::IO::BinaryWriter(fs);

// Set up file with RIFF chunk info.

array<Char>^ ChunkRiff = { 'R', 'I', 'F', 'F' };

array<Char>^ ChunkType = { 'W', 'A', 'V', 'E' };

array<Char>^ ChunkFmt = { 'f', 'm', 't', ' ' };

array<Char>^ ChunkData = { 'd', 'a', 't', 'a' };

short shPad = inpWaveFormat->wfx.wFormatTag; //49

int nFormatChunkLength = sizeof(inpWaveFormat);

// File length, minus first 8 bytes of RIFF description.

int nLength = nDataLength + 36 + inpWaveFormat->wfx.cbSize;

// Write the riff info for the wave file.

wavBinaryWriter->Write(ChunkRiff);

wavBinaryWriter->Write(nLength);

wavBinaryWriter->Write(ChunkType);

// Write the format info for the wave file.

wavBinaryWriter->Write(ChunkFmt);

wavBinaryWriter->Write(nFormatChunkLength);

wavBinaryWriter->Write(shPad);

wavBinaryWriter->Write(inpWaveFormat->wfx.nChannels);

wavBinaryWriter->Write((int)inpWaveFormat->wfx.nSamplesPerSec);

wavBinaryWriter->Write((int)inpWaveFormat->wfx.nAvgBytesPerSec);

wavBinaryWriter->Write(inpWaveFormat->wfx.nBlockAlign);

wavBinaryWriter->Write(inpWaveFormat->wfx.wBitsPerSample);

// Write the extra bytes

if (inpWaveFormat->wfx.cbSize > 0)

wavBinaryWriter->Write((int)inpWaveFormat->wSamplesPerBlock);

// Write the data chunk.

wavBinaryWriter->Write(ChunkData);

wavBinaryWriter->Write((int)nDataLength);

// Write the data

array<Byte>^ data = gcnew array<Byte>(nDataLength);

for (int i=0; i < (int)nDataLength; i++)

{

dataIdea = destBufferIdea;

}

wavBinaryWriter->Write(data, 0, nDataLength);

wavBinaryWriter->Flush();

wavBinaryWriter->Close();

return 0;

}





Re: Windows SDK ACM: Converting PCM Wave files to another format

Chris P.

Try:

nFormatChunkLength = sizeof(WAVEFORMATEX) + inpWaveFormat->wfx.cbSize;

Also you should be able to write the WaveFormat struct directly using the 3 parameter Write command, and it is not necessary to copy the data before writing it. Just write the "destBuffer" directly.






Re: Windows SDK ACM: Converting PCM Wave files to another format

VLM

I got it working. Thanks for pointing me in the right direction. The fix is that I need to write cbSize and SamplesperBlock in the format chunk.

if (inpWaveFormat->wfx.cbSize > 0)

{

wavBinaryWriter->Write(inpWaveFormat->wfx.cbSize);

wavBinaryWriter->Write(inpWaveFormat->wSamplesPerBlock);

}

I am not able to directly write the destBuffer. I get a compiler error saying that need a cli:array.





Re: Windows SDK ACM: Converting PCM Wave files to another format

Chris P.

Glad you got it working.

There probably is a solution around the Write() problem but unfortunately I don't know enough .NET to give you a solution. I think you need a byte array cast or some such.