   Pulling Audio format from an AVI file and passing to DirectSound
  Not real sure if anyone is going to know the answer to this, as it's kind of esoteric, but may as well ask, right? :)Having successfully gotten my program to play the video portion of an AVI file, I've turned my attention to the audio portion, which I want to play using DirectSound.So I set it all up and tested it, and it all works just fine, I know the sound is working. But here is the thing. I need to pull the format (in the form of a WAVEFORMATEX structure) of the audio from the AVI file (which I've done) and pass this over to DirectSound to create a secondary buffer that is compatable with the sound in the AVI file.This is the code that pulls the audio format from the AVI file (minus error checking):AVIStreamReadFormat(Audio, AVIStreamStart(Audio), NULL, &AudioFormatSize);AudioChunk = new BYTE[AudioFormatSize];AVIStreamReadFormat(Audio, AVIStreamStart(Audio), AudioChunk, &AudioFormatSize);AudioWaveFormat = (LPWAVEFORMATEX)AudioChunk;DirectSound.CreateSecondaryBuffer(AudioWaveFormat);The contents of AudioWaveFormat for my test avi are:wFormatTag: 34 nChannels: 1nSamplesPerSec: 8000nAvgBytesPerSec: 1067nBlockAlign: 32wBitsPerSample: 1cbSize: 32On an alternate AVI file I tried, I got:wFormatTag: 2nChannels: 2nSamplesPerSec: 44100nAvgBytesPerSec: 44359nBlockAlign: 2048wBitsPerSample: 4cbSize: 32(I tried to look up the wFormatTag values to see which one corresponds with a WAVE_FORMAT_PCM, but could find it nowhere, so I have no clue what 32 or 2 means in those fields). So anyway, I pass this structure over DirectSound so it can create my secondary buffer with those parameters, like so:HRESULT DirectSoundClass::CreateSecondaryBuffer(LPWAVEFORMATEX WaveFormat)    {    HRESULT r;    ostringstream ss;    static char FunctionString[] = "DirectSoundClass::CreateSecondaryBuffer()";    DSBUFFERDESC dsbdesc;    LPDIRECTSOUNDBUFFER pDsb;    // Create a secondary buffer.    // Set up DSBUFFERDESC structure.    memset(&dsbdesc, 0, sizeof(DSBUFFERDESC));    dsbdesc.dwSize = sizeof(DSBUFFERDESC);    dsbdesc.dwFlags = DSBCAPS_CTRLPAN | DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLFREQUENCY | DSBCAPS_GLOBALFOCUS | DSBCAPS_GETCURRENTPOSITION2;    dsbdesc.dwBufferBytes = 3 * WaveFormat->nAvgBytesPerSec;    dsbdesc.lpwfxFormat = WaveFormat;    r = DirectSoundDevice->CreateSoundBuffer(&dsbdesc, &pDsb, NULL);    r = pDsb->QueryInterface(IID_IDirectSoundBuffer8, (void**)&DirectSoundBuffer);    pDsb->Release();    }What both files gives me is an error:"Unable to create a secondary buffer for DirectSound  DirectSoundClass::CreateSecondaryBuffer(): An invalid parameter was passed to the returning function - E_INVALIDARG"Now, if I replace the WaveFormat structure with my own structure, like this:HRESULT DirectSoundClass::CreateSecondaryBuffer(LPWAVEFORMATEX WaveFormat)    {    HRESULT r;    ostringstream ss;    static char FunctionString[] = "DirectSoundClass::CreateSecondaryBuffer()";    DSBUFFERDESC dsbdesc;    LPDIRECTSOUNDBUFFER pDsb;    WAVEFORMATEX wfx;    // Create a secondary buffer.    memset(&wfx, 0, sizeof(WAVEFORMATEX));    wfx.wFormatTag = WAVE_FORMAT_PCM;    wfx.nChannels = 1;    wfx.nSamplesPerSec = 22050;    wfx.wBitsPerSample = 16;    wfx.nBlockAlign = (WORD)((wfx.wBitsPerSample/8) * wfx.nChannels);    wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;    // Set up DSBUFFERDESC structure.    memset(&dsbdesc, 0, sizeof(DSBUFFERDESC));    dsbdesc.dwSize = sizeof(DSBUFFERDESC);    dsbdesc.dwFlags = DSBCAPS_CTRLPAN | DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLFREQUENCY | DSBCAPS_GLOBALFOCUS | DSBCAPS_GETCURRENTPOSITION2;    dsbdesc.dwBufferBytes = 3 * wfx.nAvgBytesPerSec;    dsbdesc.lpwfxFormat = &wfx    r = DirectSoundDevice->CreateSoundBuffer(&dsbdesc, &pDsb, NULL);    r = pDsb->QueryInterface(IID_IDirectSoundBuffer8, (void**)&DirectSoundBuffer);    pDsb->Release();    }it plays the sound. However, since the format of the sound coming from the AVI is not the same as the format in the DSound buffer, it plays distorted.So, the question is, why, when I send the correct format from the AVI file to my DSound routine, do I get a parameter error, and more importantly, how do I make it work? I'd be grateful for any advice if anyone has run into anything similar.   
  Well, I've subsequently found the wFormatTag definitions in one of the header files, and determined the one I want (WAVE_FORMAT_PCM) is equal to 1. So neither of my test AVIs store sound in a format supported by DirectSound. Which is probably the reason why things are not working.I've also run across the acmStreamXXX family of functions, which seem to be designed to convert between various forms of WAVEFORMATs, so preliminarily, at least, it looks like I can use those to convert my buffer data from the AVI into a second buffer that is in the format that DS will like (although the functions seem to require codecs, but I *presume* codecs for all the major wave formats will exist on users machines, is that a safe assumption to make?)Once I've finished coding it and testing it, I'll post the final code (because I absolutely HATE when people ask a question then figure out the answer but don't bother to post it, I run across that all too often when doing research, and it drives me insane).   ;  Just in case you hadn't already found it, DirectShow was made for this kind of business. If it's not too late to turn back (and it never really is), you may want to investigate DShow's demuxing capabilities.Admiral   ;  Hey Admiral,Yes, I know of DirectShow. I used it in a previous project called Sovereignty. And yes, I did consider it for this project.The only reason I didn't use it here is because I'm already using D3D and DSound for my program, and setting up DShow JUST to play AVIs (and that's all I would be using it for) seemed like duplication of stuff I already have working in the program. Perhaps that was a bad decision, and DShow is a better way to go. But since I already have video running through D3D and am pretty close to having the sound running through DSound, I'll continue on this path. If I run into complications or just can't get it to work right, I'll look into switching over to DShow.But you guys can tell me if I'm totally wrong on this one :D   ;  Well Admiral, you were right, I was wrong.After setting up all the conversion stuff, I succeeded only in getting a 512 error, which maps to "conversion not possible". Swell.So I threw up my hands in defeat, ripped all that out and redid the whole thing with DShow. Took a couple of hours (and that's with having to write a string->wstring converter which took the majority of that time) and it works fine.Could have saved myself a couple days worth of coding if I had done that in the first place. Ah well, live and learn, huh? :)   