Hi there,
I've encountered a strange issue with the waveOut API's and I'm not sure if its by design or if I'm missing something.
Basically If I open a device specifying that the default communication device is to be used, that device will always cause ducking/stream attenuation to occur for all future uses of said device. Even when I no longer specify that the default communications device should be used.
I've found some crude sample code to try and explain:
#include <windows.h> #include <mmsystem.h> #include <stdio.h> typedef struct wavFileHeader { long chunkId; //"RIFF" (0x52,0x49,0x46,0x46) long chunkSize; // (fileSize - 8) - could also be thought of as bytes of data in file following this field (bytesRemaining) long riffType; // "WAVE" (0x57415645) }; typedef struct fmtChunk { long chunkId; // "fmt " - (0x666D7420) long chunkDataSize; // 16 + extra format bytes short compressionCode; // 1 - 65535 short numChannels; // 1 - 65535 long sampleRate; // 1 - 0xFFFFFFFF long avgBytesPerSec; // 1 - 0xFFFFFFFF short blockAlign; // 1 - 65535 short significantBitsPerSample; // 2 - 65535 short extraFormatBytes; // 0 - 65535 }; typedef struct wavChunk { long chunkId; long chunkDataSize; }; char *readFileData(char *szFilename, long &dataLengthOut) { FILE *fp = fopen(szFilename, "rb"); long len; char *buffer; fseek(fp, 0, SEEK_END); len = ftell(fp); fseek(fp, 0, SEEK_SET); buffer = (char*)calloc(1, len + 1); fread(buffer, 1, len, fp); fclose(fp); dataLengthOut = len; return buffer; } void parseWav(char *data, bool playDefaultComm) { long *mPtr; char *tmpPtr; char *buffer; WAVEFORMATEX wf; volatile WAVEHDR wh; HWAVEOUT hWaveOut; fmtChunk mFmtChunk; wavChunk mDataChunk; mPtr = (long*)data; if (mPtr[0] == 0x46464952) // little endian check for 'RIFF' { mPtr += 3; if (mPtr[0] == 0x20746D66) // little endian for "fmt " { // printf("Format chunk found\n"); tmpPtr = (char*)mPtr; memcpy(&mFmtChunk, tmpPtr, sizeof(mFmtChunk)); tmpPtr += 8; tmpPtr += mFmtChunk.chunkDataSize; mPtr = (long*)tmpPtr; if (mPtr[0] == 0x61746164) // little endian for "data" { // printf("Data chunk found\n"); tmpPtr = (char*)mPtr; memcpy(&mDataChunk, tmpPtr, sizeof(mDataChunk)); mPtr += 2; buffer = (char*)malloc(mDataChunk.chunkDataSize); memcpy(buffer, mPtr, mDataChunk.chunkDataSize); printf("sampleRate: %d\n", mFmtChunk.sampleRate); wf.wFormatTag = mFmtChunk.compressionCode; wf.nChannels = mFmtChunk.numChannels; wf.nSamplesPerSec = mFmtChunk.sampleRate; wf.nAvgBytesPerSec = mFmtChunk.avgBytesPerSec; wf.nBlockAlign = mFmtChunk.blockAlign; wf.wBitsPerSample = mFmtChunk.significantBitsPerSample; wf.cbSize = mFmtChunk.extraFormatBytes; wh.lpData = buffer; wh.dwBufferLength = mDataChunk.chunkDataSize; wh.dwFlags = 0; wh.dwLoops = 0; if (playDefaultComm) { waveOutOpen(&hWaveOut, WAVE_MAPPER, &wf, 0, 0, WAVE_MAPPED_DEFAULT_COMMUNICATION_DEVICE); } else { //Make sure the device ID is set to your default communications device. waveOutOpen(&hWaveOut, 1, &wf, 0, 0, CALLBACK_NULL); } waveOutPrepareHeader(hWaveOut, (wavehdr_tag*)&wh, sizeof(wh)); waveOutWrite(hWaveOut, (wavehdr_tag*)&wh, sizeof(wh)); do {} while (!(wh.dwFlags & WHDR_DONE)); waveOutUnprepareHeader(hWaveOut, (wavehdr_tag*)&wh, sizeof(wh)); waveOutClose(hWaveOut); free(buffer); } } } else printf("INvalid WAV\n"); } int main() { //choose your file to play char *filename = "c:/windows/media/tada.wav"; char *buffer; long fileSize; buffer = readFileData(filename, fileSize); //play the .wav using the default communications device.
//Ducks audio as expected parseWav(buffer, true); //play the .wav using the specified device. (continues to cause ducking for some reason) parseWav(buffer, false); free(buffer); return 0; }
If I call the parseWav(buffer,false) first, ducking will not occur.
Its only if I attempt to specify the default communications device that it continues to duck no matter what.
Thanks for your help,
Cathal
Edit:
To clarify what I'm trying to achieve:
I want to play two separate files on the same device.
One will cause ducking, the other will not.