DirectSound
时间:2014-04-18
来源:互联网
正在写DirectSound...
汪汪不知道...为何每次Call SoundStream::Write时....声音都会断开的(爆音)...
汪汪不知道...为何每次Call SoundStream::Write时....声音都会断开的(爆音)...

复制内容到剪贴板代码:class SoundDevice;
class SoundStream
{
IDirectSoundBuffer8 * soundbuffer;
const WORD channel, bits, validBits;
const DWORD frequency, blockBytes;
uint8_t * buffer;
size_t bufferBytes;
std::thread thread;
std::mutex mutex;
HANDLE flag;
bool decompose;
SoundStream(IDirectSoundBuffer8 * pDsb8, WORD getChannel, WORD getBits, WORD getValidBits, DWORD getFrequency, DWORD getBlockBytes);
public:
friend SoundDevice;
~SoundStream();
DWORD PlayCursor();
DWORD WriteCursor();
DWORD CursorDiff();
DWORD RemainTime();
void Write(const multiarray<double, 2> &data);
void Clear();
void Sync();
private:
DWORD _diff(DWORD first, DWORD second);
};
class SoundDevice
{
IDirectSound8 * device;
public:
SoundDevice(HWND hWnd);
~SoundDevice();
SoundStream * Channel_1(DWORD fq);
SoundStream * Channel_2(DWORD fq);
SoundStream * Channel_4(DWORD fq);
SoundStream * Channel_5_1(DWORD fq);
private:
SoundStream * CreateBuffer(LPWAVEFORMATEX wfx, WORD validBits, DWORD frequency);
};
void SoundStream::Write(const multiarray<double, 2> &data)
{
if (data.size(0) != channel || data.size(1) == 0) return;
std::lock_guard<std::mutex> lock(mutex);
const int64_t max = 1 << ((int64_t)validBits - 1), min = ~max;
const size_t oldBytes = bufferBytes;
uint8_t * _buffer = buffer;
bufferBytes = data.size() * (bits >> 3) + oldBytes;
buffer = new uint8_t[(size_t)(bufferBytes + ((bits >> 3) % 8 ? 8 - ((bits >> 3) % 8) : 0))];
if (_buffer != nullptr)
{
memcpy(buffer, _buffer, (size_t)oldBytes);
delete[] _buffer;
}
for (size_t i = 0; i < data.size(1); ++i)
{
for (size_t j = 0; j < channel; ++j)
{
int64_t *ptr = (int64_t*)(buffer + oldBytes + (i * channel + j) * (bits >> 3));
*ptr = (int64_t)bound(data[(size_t)j][(size_t)i], (double)max, (double)min);
}
}
SetEvent(flag);
}
void SoundStream::Sync()
{
static DWORD CursorRecord = 0;
std::lock_guard<std::mutex> lock(mutex);
DWORD Cursor = WriteCursor(), MaxWriteBytes = blockBytes * 2 - (Cursor % blockBytes);
LPVOID bufferPtr[2];
DWORD _bufferBytes[2];
HResult(soundbuffer->Lock(Cursor, MaxWriteBytes, &bufferPtr[0], &_bufferBytes[0], &bufferPtr[1], &_bufferBytes[1], 0));
DWORD ChoppedBytes[2];
ChoppedBytes[0] = min(_bufferBytes[0], (DWORD)bufferBytes);
ChoppedBytes[1] = min(_bufferBytes[1], (DWORD)bufferBytes - ChoppedBytes[0]);
memcpy(bufferPtr[0], buffer, ChoppedBytes[0]);
memcpy(bufferPtr[1], buffer + _bufferBytes[0], ChoppedBytes[1]);
memset((uint8_t*)bufferPtr[0] + ChoppedBytes[0], 0, _bufferBytes[0] - ChoppedBytes[0]);
memset((uint8_t*)bufferPtr[1] + ChoppedBytes[1], 0, _bufferBytes[1] - ChoppedBytes[1]);
HResult(soundbuffer->Unlock(bufferPtr[0], _bufferBytes[0], bufferPtr[1], _bufferBytes[1]));
uint8_t * _buffer = buffer;
DWORD offset = min(_diff(Cursor, CursorRecord), ChoppedBytes[0] + ChoppedBytes[1]);
CursorRecord = Cursor;
bufferBytes -= offset;
if (bufferBytes)
buffer = new uint8_t[(size_t)bufferBytes];
else
buffer = nullptr;
if (_buffer != nullptr)
{
if (buffer != nullptr)
memcpy(buffer, _buffer + offset, (size_t)bufferBytes);
delete[] _buffer;
}
}
class SoundStream
{
IDirectSoundBuffer8 * soundbuffer;
const WORD channel, bits, validBits;
const DWORD frequency, blockBytes;
uint8_t * buffer;
size_t bufferBytes;
std::thread thread;
std::mutex mutex;
HANDLE flag;
bool decompose;
SoundStream(IDirectSoundBuffer8 * pDsb8, WORD getChannel, WORD getBits, WORD getValidBits, DWORD getFrequency, DWORD getBlockBytes);
public:
friend SoundDevice;
~SoundStream();
DWORD PlayCursor();
DWORD WriteCursor();
DWORD CursorDiff();
DWORD RemainTime();
void Write(const multiarray<double, 2> &data);
void Clear();
void Sync();
private:
DWORD _diff(DWORD first, DWORD second);
};
class SoundDevice
{
IDirectSound8 * device;
public:
SoundDevice(HWND hWnd);
~SoundDevice();
SoundStream * Channel_1(DWORD fq);
SoundStream * Channel_2(DWORD fq);
SoundStream * Channel_4(DWORD fq);
SoundStream * Channel_5_1(DWORD fq);
private:
SoundStream * CreateBuffer(LPWAVEFORMATEX wfx, WORD validBits, DWORD frequency);
};
void SoundStream::Write(const multiarray<double, 2> &data)
{
if (data.size(0) != channel || data.size(1) == 0) return;
std::lock_guard<std::mutex> lock(mutex);
const int64_t max = 1 << ((int64_t)validBits - 1), min = ~max;
const size_t oldBytes = bufferBytes;
uint8_t * _buffer = buffer;
bufferBytes = data.size() * (bits >> 3) + oldBytes;
buffer = new uint8_t[(size_t)(bufferBytes + ((bits >> 3) % 8 ? 8 - ((bits >> 3) % 8) : 0))];
if (_buffer != nullptr)
{
memcpy(buffer, _buffer, (size_t)oldBytes);
delete[] _buffer;
}
for (size_t i = 0; i < data.size(1); ++i)
{
for (size_t j = 0; j < channel; ++j)
{
int64_t *ptr = (int64_t*)(buffer + oldBytes + (i * channel + j) * (bits >> 3));
*ptr = (int64_t)bound(data[(size_t)j][(size_t)i], (double)max, (double)min);
}
}
SetEvent(flag);
}
void SoundStream::Sync()
{
static DWORD CursorRecord = 0;
std::lock_guard<std::mutex> lock(mutex);
DWORD Cursor = WriteCursor(), MaxWriteBytes = blockBytes * 2 - (Cursor % blockBytes);
LPVOID bufferPtr[2];
DWORD _bufferBytes[2];
HResult(soundbuffer->Lock(Cursor, MaxWriteBytes, &bufferPtr[0], &_bufferBytes[0], &bufferPtr[1], &_bufferBytes[1], 0));
DWORD ChoppedBytes[2];
ChoppedBytes[0] = min(_bufferBytes[0], (DWORD)bufferBytes);
ChoppedBytes[1] = min(_bufferBytes[1], (DWORD)bufferBytes - ChoppedBytes[0]);
memcpy(bufferPtr[0], buffer, ChoppedBytes[0]);
memcpy(bufferPtr[1], buffer + _bufferBytes[0], ChoppedBytes[1]);
memset((uint8_t*)bufferPtr[0] + ChoppedBytes[0], 0, _bufferBytes[0] - ChoppedBytes[0]);
memset((uint8_t*)bufferPtr[1] + ChoppedBytes[1], 0, _bufferBytes[1] - ChoppedBytes[1]);
HResult(soundbuffer->Unlock(bufferPtr[0], _bufferBytes[0], bufferPtr[1], _bufferBytes[1]));
uint8_t * _buffer = buffer;
DWORD offset = min(_diff(Cursor, CursorRecord), ChoppedBytes[0] + ChoppedBytes[1]);
CursorRecord = Cursor;
bufferBytes -= offset;
if (bufferBytes)
buffer = new uint8_t[(size_t)bufferBytes];
else
buffer = nullptr;
if (_buffer != nullptr)
{
if (buffer != nullptr)
memcpy(buffer, _buffer + offset, (size_t)bufferBytes);
delete[] _buffer;
}
}
作者: Susan﹏汪汪 发布时间: 2014-04-18
点解重用 DirectSound?DirectSound 已经被 WASAPI 所取代。
我无用过 DirectSound,根据我用过 Allegro 嘅经验,以下系一尐可能性:
1. buffer size 计算有误(过长或过短)
2. 时间性出错
3. 计算 buffer 内容有偏差,如用咗 real numbers,又或整数计算时,出现 overflow 或 underflow
我无用过 DirectSound,根据我用过 Allegro 嘅经验,以下系一尐可能性:
1. buffer size 计算有误(过长或过短)
2. 时间性出错
3. 计算 buffer 内容有偏差,如用咗 real numbers,又或整数计算时,出现 overflow 或 underflow
作者: fitcat07 发布时间: 2014-04-18
引用:原帖由 fitcat07 於 2014-3-20 01:03 PM 发表
点解重用 DirectSound?DirectSound 已经被 WASAPI 所取代。
我无用过 DirectSound,根据我用过 Allegro 嘅经验,以下系一尐可能性:
1. buffer size 计算有误(过长或过短)
2. 时间性出错
3. 计算 buf ...
今晚换wasapi吧 点解重用 DirectSound?DirectSound 已经被 WASAPI 所取代。
我无用过 DirectSound,根据我用过 Allegro 嘅经验,以下系一尐可能性:
1. buffer size 计算有误(过长或过短)
2. 时间性出错
3. 计算 buf ...
作者: Susan﹏汪汪 发布时间: 2014-04-18
汪汪不知道为甚么会完全冇声

复制内容到剪贴板代码:class SoundStream
{
IAudioClient * pAudioClient;
std::thread thread;
std::mutex mtx;
HANDLE hEvent;
BYTE * buffer;
size_t bufferSize;
UINT32 bufferFrameCount, channel, bits, validBits, frequency;
bool distroy;
void _writebuffer();
public:
SoundStream(_AUDCLNT_SHAREMODE ShareMode = AUDCLNT_SHAREMODE_SHARED);
~SoundStream();
UINT32 Channel()
{
return channel;
}
UINT32 Frequency()
{
return frequency;
}
UINT32 Bits()
{
return bits;
}
UINT32 ValidBits()
{
return validBits;
}
void Write(const multiarray<double, 2> &data);
void Sync();
};
// REFERENCE_TIME time units per second and per millisecond
#define REFTIMES_PER_SEC 10000000
#define REFTIMES_PER_MILLISEC 10000
SoundStream::SoundStream(_AUDCLNT_SHAREMODE ShareMode) : buffer(nullptr), bufferSize(0), distroy(false)
{
IMMDeviceEnumerator * pEnumerator = nullptr;
HResult(CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_ALL, IID_PPV_ARGS(&pEnumerator)));
IMMDevice * pDevice = nullptr;
HResult(pEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &pDevice));
SafeRelease(&pEnumerator);
HResult(pDevice->Activate(__uuidof(IAudioClient), CLSCTX_ALL, NULL, (void**)&pAudioClient));
SafeRelease(&pDevice);
WAVEFORMATEXTENSIBLE * pwfx = nullptr;
hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (ShareMode == AUDCLNT_SHAREMODE_SHARED)
{
REFERENCE_TIME hnsRequestedDuration = REFTIMES_PER_SEC;
HResult(pAudioClient->GetMixFormat((WAVEFORMATEX**)&pwfx));
HResult(pAudioClient->Initialize(
AUDCLNT_SHAREMODE_SHARED,
0,
hnsRequestedDuration,
0,
(WAVEFORMATEX*)pwfx,
NULL));
} else
{
REFERENCE_TIME hnsRequestedDuration;
HResult(GetStreamFormat(pAudioClient, &pwfx));
HResult(pAudioClient->GetDevicePeriod(NULL, &hnsRequestedDuration));
HResult(pAudioClient->Initialize(
AUDCLNT_SHAREMODE_EXCLUSIVE,
AUDCLNT_STREAMFLAGS_EVENTCALLBACK,
hnsRequestedDuration,
hnsRequestedDuration,
(WAVEFORMATEX*)pwfx,
NULL));
HResult(pAudioClient->SetEventHandle(hEvent));
}
channel = (size_t)pwfx->Format.nChannels;
bits = (size_t)pwfx->Format.wBitsPerSample;
validBits = (size_t)pwfx->Samples.wValidBitsPerSample;
frequency = (size_t)pwfx->Format.nSamplesPerSec;
CoTaskMemFree(pwfx);
HResult(pAudioClient->GetBufferSize(&bufferFrameCount));
HResult(pAudioClient->Start());
if (pAudioClient)
{
thread = std::thread([&]()
{
this->Sync();
});
}
}
SoundStream::~SoundStream()
{
if (pAudioClient)
{
distroy = true;
SetEvent(hEvent);
thread.join();
HResult(pAudioClient->Stop());
SafeRelease(&pAudioClient);
}
if (hEvent != NULL)
CloseHandle(hEvent);
if (bufferSize)
delete[] buffer;
}
void SoundStream::Write(const multiarray<double, 2> &data)
{
std::lock_guard<std::mutex> lck(mtx);
const int64_t min = 1 << ((int64_t)validBits - 1), max = ~min;
size_t blockSize = channel * (bits >> 3), oldBufferSize = bufferSize;
bufferSize += data.size(1) * blockSize;
if (oldBufferSize)
{
BYTE * _buffer = buffer;
buffer = new BYTE[bufferSize + ((bits >> 3) % 8 ? 8 - (bits >> 3) % 8 : 0)];
memcpy(buffer, _buffer, oldBufferSize);
delete[] _buffer;
} else
buffer = new BYTE[bufferSize + ((bits >> 3) % 8 ? 8 - (bits >> 3) % 8 : 0)];
for (size_t i = 0; i < data.size(1); ++i)
{
for (size_t j = 0; j < data.size(0) && j < channel; ++j)
{
int64_t * ptr = (int64_t*)(buffer + oldBufferSize + i * blockSize + j * (bits >> 3));
if (data[j][i] > 1)
*ptr = (int64_t)bound(1, (double)max, (double)min);
else if (data[j][i] < -1)
*ptr = (int64_t)bound(-1, (double)max, (double)min);
else
*ptr = (int64_t)bound(data[j][i], (double)max, (double)min);
}
}
SetEvent(hEvent);
}
void SoundStream::Sync()
{
const REFERENCE_TIME hnsActualDuration = (REFERENCE_TIME)(REFTIMES_PER_SEC * bufferFrameCount / frequency);
while (!distroy)
{
WaitForSingleObject(hEvent, (DWORD)(hnsActualDuration / REFTIMES_PER_MILLISEC / 2));
if (!distroy) _writebuffer();
}
}
void SoundStream::_writebuffer()
{
std::lock_guard<std::mutex> lck(mtx);
UINT32 numFramesPadding;
HResult(pAudioClient->GetCurrentPadding(&numFramesPadding));
size_t blockSize = channel * (bits >> 3),
ChoppedBytes = min(blockSize * (size_t)(bufferFrameCount - numFramesPadding), bufferSize);
if (ChoppedBytes)
{
IAudioRenderClient * pRenderClient = nullptr;
HResult(pAudioClient->GetService(IID_PPV_ARGS(&pRenderClient)));
BYTE * pData = nullptr;
HResult(pRenderClient->GetBuffer((UINT32)(ChoppedBytes / blockSize), &pData));
memcpy(pData, buffer, ChoppedBytes);
HResult(pRenderClient->ReleaseBuffer((UINT32)(ChoppedBytes / blockSize), 0));
SafeRelease(&pRenderClient);
if (bufferSize -= ChoppedBytes)
{
BYTE * _buffer = buffer;
buffer = new BYTE[bufferSize];
memcpy(buffer, _buffer + ChoppedBytes, bufferSize);
delete[] _buffer;
} else
{
if (buffer != nullptr)
{
delete[] buffer;
buffer = nullptr;
}
}
}
}
[ 本帖最后由 Susan﹏汪汪 於 2014-3-21 03:16 AM 编辑 ] {
IAudioClient * pAudioClient;
std::thread thread;
std::mutex mtx;
HANDLE hEvent;
BYTE * buffer;
size_t bufferSize;
UINT32 bufferFrameCount, channel, bits, validBits, frequency;
bool distroy;
void _writebuffer();
public:
SoundStream(_AUDCLNT_SHAREMODE ShareMode = AUDCLNT_SHAREMODE_SHARED);
~SoundStream();
UINT32 Channel()
{
return channel;
}
UINT32 Frequency()
{
return frequency;
}
UINT32 Bits()
{
return bits;
}
UINT32 ValidBits()
{
return validBits;
}
void Write(const multiarray<double, 2> &data);
void Sync();
};
// REFERENCE_TIME time units per second and per millisecond
#define REFTIMES_PER_SEC 10000000
#define REFTIMES_PER_MILLISEC 10000
SoundStream::SoundStream(_AUDCLNT_SHAREMODE ShareMode) : buffer(nullptr), bufferSize(0), distroy(false)
{
IMMDeviceEnumerator * pEnumerator = nullptr;
HResult(CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_ALL, IID_PPV_ARGS(&pEnumerator)));
IMMDevice * pDevice = nullptr;
HResult(pEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &pDevice));
SafeRelease(&pEnumerator);
HResult(pDevice->Activate(__uuidof(IAudioClient), CLSCTX_ALL, NULL, (void**)&pAudioClient));
SafeRelease(&pDevice);
WAVEFORMATEXTENSIBLE * pwfx = nullptr;
hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (ShareMode == AUDCLNT_SHAREMODE_SHARED)
{
REFERENCE_TIME hnsRequestedDuration = REFTIMES_PER_SEC;
HResult(pAudioClient->GetMixFormat((WAVEFORMATEX**)&pwfx));
HResult(pAudioClient->Initialize(
AUDCLNT_SHAREMODE_SHARED,
0,
hnsRequestedDuration,
0,
(WAVEFORMATEX*)pwfx,
NULL));
} else
{
REFERENCE_TIME hnsRequestedDuration;
HResult(GetStreamFormat(pAudioClient, &pwfx));
HResult(pAudioClient->GetDevicePeriod(NULL, &hnsRequestedDuration));
HResult(pAudioClient->Initialize(
AUDCLNT_SHAREMODE_EXCLUSIVE,
AUDCLNT_STREAMFLAGS_EVENTCALLBACK,
hnsRequestedDuration,
hnsRequestedDuration,
(WAVEFORMATEX*)pwfx,
NULL));
HResult(pAudioClient->SetEventHandle(hEvent));
}
channel = (size_t)pwfx->Format.nChannels;
bits = (size_t)pwfx->Format.wBitsPerSample;
validBits = (size_t)pwfx->Samples.wValidBitsPerSample;
frequency = (size_t)pwfx->Format.nSamplesPerSec;
CoTaskMemFree(pwfx);
HResult(pAudioClient->GetBufferSize(&bufferFrameCount));
HResult(pAudioClient->Start());
if (pAudioClient)
{
thread = std::thread([&]()
{
this->Sync();
});
}
}
SoundStream::~SoundStream()
{
if (pAudioClient)
{
distroy = true;
SetEvent(hEvent);
thread.join();
HResult(pAudioClient->Stop());
SafeRelease(&pAudioClient);
}
if (hEvent != NULL)
CloseHandle(hEvent);
if (bufferSize)
delete[] buffer;
}
void SoundStream::Write(const multiarray<double, 2> &data)
{
std::lock_guard<std::mutex> lck(mtx);
const int64_t min = 1 << ((int64_t)validBits - 1), max = ~min;
size_t blockSize = channel * (bits >> 3), oldBufferSize = bufferSize;
bufferSize += data.size(1) * blockSize;
if (oldBufferSize)
{
BYTE * _buffer = buffer;
buffer = new BYTE[bufferSize + ((bits >> 3) % 8 ? 8 - (bits >> 3) % 8 : 0)];
memcpy(buffer, _buffer, oldBufferSize);
delete[] _buffer;
} else
buffer = new BYTE[bufferSize + ((bits >> 3) % 8 ? 8 - (bits >> 3) % 8 : 0)];
for (size_t i = 0; i < data.size(1); ++i)
{
for (size_t j = 0; j < data.size(0) && j < channel; ++j)
{
int64_t * ptr = (int64_t*)(buffer + oldBufferSize + i * blockSize + j * (bits >> 3));
if (data[j][i] > 1)
*ptr = (int64_t)bound(1, (double)max, (double)min);
else if (data[j][i] < -1)
*ptr = (int64_t)bound(-1, (double)max, (double)min);
else
*ptr = (int64_t)bound(data[j][i], (double)max, (double)min);
}
}
SetEvent(hEvent);
}
void SoundStream::Sync()
{
const REFERENCE_TIME hnsActualDuration = (REFERENCE_TIME)(REFTIMES_PER_SEC * bufferFrameCount / frequency);
while (!distroy)
{
WaitForSingleObject(hEvent, (DWORD)(hnsActualDuration / REFTIMES_PER_MILLISEC / 2));
if (!distroy) _writebuffer();
}
}
void SoundStream::_writebuffer()
{
std::lock_guard<std::mutex> lck(mtx);
UINT32 numFramesPadding;
HResult(pAudioClient->GetCurrentPadding(&numFramesPadding));
size_t blockSize = channel * (bits >> 3),
ChoppedBytes = min(blockSize * (size_t)(bufferFrameCount - numFramesPadding), bufferSize);
if (ChoppedBytes)
{
IAudioRenderClient * pRenderClient = nullptr;
HResult(pAudioClient->GetService(IID_PPV_ARGS(&pRenderClient)));
BYTE * pData = nullptr;
HResult(pRenderClient->GetBuffer((UINT32)(ChoppedBytes / blockSize), &pData));
memcpy(pData, buffer, ChoppedBytes);
HResult(pRenderClient->ReleaseBuffer((UINT32)(ChoppedBytes / blockSize), 0));
SafeRelease(&pRenderClient);
if (bufferSize -= ChoppedBytes)
{
BYTE * _buffer = buffer;
buffer = new BYTE[bufferSize];
memcpy(buffer, _buffer + ChoppedBytes, bufferSize);
delete[] _buffer;
} else
{
if (buffer != nullptr)
{
delete[] buffer;
buffer = nullptr;
}
}
}
}
作者: Susan﹏汪汪 发布时间: 2014-04-18
GetStreamFormat
复制内容到剪贴板代码:HRESULT GetStreamFormat(IAudioClient * pAudioClient, WAVEFORMATEXTENSIBLE ** pwfx)
{
HRESULT hr;
WAVEFORMATEXTENSIBLE wfx;
wfx.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
wfx.Format.nChannels = 6;
wfx.Format.wBitsPerSample = 24;
wfx.Samples.wValidBitsPerSample = 20;
wfx.dwChannelMask = KSAUDIO_SPEAKER_5POINT1;
wfx.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
wfx.Format.nSamplesPerSec = 48000;
wfx.Format.nBlockAlign = wfx.Format.nChannels * wfx.Format.wBitsPerSample / 8;
wfx.Format.nAvgBytesPerSec = wfx.Format.nSamplesPerSec * wfx.Format.nBlockAlign;
wfx.Format.cbSize = 34;
hr = pAudioClient->IsFormatSupported(AUDCLNT_SHAREMODE_EXCLUSIVE, (WAVEFORMATEX*)&wfx, (WAVEFORMATEX**)pwfx);
if (hr == S_OK)
{
*pwfx = (WAVEFORMATEXTENSIBLE*)CoTaskMemAlloc(sizeof(WAVEFORMATEXTENSIBLE));
memcpy(*pwfx, &wfx, sizeof(WAVEFORMATEXTENSIBLE));
return hr;
} else if (hr == S_FALSE) return hr;
wfx.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
wfx.Format.nChannels = 6;
wfx.Format.wBitsPerSample = 24;
wfx.Samples.wValidBitsPerSample = 20;
wfx.dwChannelMask = KSAUDIO_SPEAKER_5POINT1;
wfx.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
wfx.Format.nSamplesPerSec = 44100;
wfx.Format.nBlockAlign = wfx.Format.nChannels * wfx.Format.wBitsPerSample / 8;
wfx.Format.nAvgBytesPerSec = wfx.Format.nSamplesPerSec * wfx.Format.nBlockAlign;
wfx.Format.cbSize = 34;
hr = pAudioClient->IsFormatSupported(AUDCLNT_SHAREMODE_EXCLUSIVE, (WAVEFORMATEX*)&wfx, (WAVEFORMATEX**)pwfx);
if (hr == S_OK)
{
*pwfx = (WAVEFORMATEXTENSIBLE*)CoTaskMemAlloc(sizeof(WAVEFORMATEXTENSIBLE));
memcpy(*pwfx, &wfx, sizeof(WAVEFORMATEXTENSIBLE));
return hr;
} else if (hr == S_FALSE) return hr;
wfx.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
wfx.Format.nChannels = 4;
wfx.Format.wBitsPerSample = 16;
wfx.Samples.wValidBitsPerSample = 16;
wfx.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT;
wfx.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
wfx.Format.nSamplesPerSec = 48000;
wfx.Format.nBlockAlign = wfx.Format.nChannels * wfx.Format.wBitsPerSample / 8;
wfx.Format.nAvgBytesPerSec = wfx.Format.nSamplesPerSec * wfx.Format.nBlockAlign;
wfx.Format.cbSize = 34;
hr = pAudioClient->IsFormatSupported(AUDCLNT_SHAREMODE_EXCLUSIVE, (WAVEFORMATEX*)&wfx, (WAVEFORMATEX**)pwfx);
if (hr == S_OK)
{
*pwfx = (WAVEFORMATEXTENSIBLE*)CoTaskMemAlloc(sizeof(WAVEFORMATEXTENSIBLE));
memcpy(*pwfx, &wfx, sizeof(WAVEFORMATEXTENSIBLE));
return hr;
} else if (hr == S_FALSE) return hr;
wfx.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
wfx.Format.nChannels = 4;
wfx.Format.wBitsPerSample = 16;
wfx.Samples.wValidBitsPerSample = 16;
wfx.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT;
wfx.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
wfx.Format.nSamplesPerSec = 44100;
wfx.Format.nBlockAlign = wfx.Format.nChannels * wfx.Format.wBitsPerSample / 8;
wfx.Format.nAvgBytesPerSec = wfx.Format.nSamplesPerSec * wfx.Format.nBlockAlign;
wfx.Format.cbSize = 34;
hr = pAudioClient->IsFormatSupported(AUDCLNT_SHAREMODE_EXCLUSIVE, (WAVEFORMATEX*)&wfx, (WAVEFORMATEX**)pwfx);
if (hr == S_OK)
{
*pwfx = (WAVEFORMATEXTENSIBLE*)CoTaskMemAlloc(sizeof(WAVEFORMATEXTENSIBLE));
memcpy(*pwfx, &wfx, sizeof(WAVEFORMATEXTENSIBLE));
return hr;
} else if (hr == S_FALSE) return hr;
wfx.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
wfx.Format.nChannels = 2;
wfx.Format.wBitsPerSample = 24;
wfx.Samples.wValidBitsPerSample = 20;
wfx.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT;
wfx.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
wfx.Format.nSamplesPerSec = 48000;
wfx.Format.nBlockAlign = wfx.Format.nChannels * wfx.Format.wBitsPerSample / 8;
wfx.Format.nAvgBytesPerSec = wfx.Format.nSamplesPerSec * wfx.Format.nBlockAlign;
wfx.Format.cbSize = 34;
hr = pAudioClient->IsFormatSupported(AUDCLNT_SHAREMODE_EXCLUSIVE, (WAVEFORMATEX*)&wfx, (WAVEFORMATEX**)pwfx);
if (hr == S_OK)
{
*pwfx = (WAVEFORMATEXTENSIBLE*)CoTaskMemAlloc(sizeof(WAVEFORMATEXTENSIBLE));
memcpy(*pwfx, &wfx, sizeof(WAVEFORMATEXTENSIBLE));
return hr;
} else if (hr == S_FALSE) return hr;
wfx.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
wfx.Format.nChannels = 2;
wfx.Format.wBitsPerSample = 24;
wfx.Samples.wValidBitsPerSample = 20;
wfx.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT;
wfx.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
wfx.Format.nSamplesPerSec = 44100;
wfx.Format.nBlockAlign = wfx.Format.nChannels * wfx.Format.wBitsPerSample / 8;
wfx.Format.nAvgBytesPerSec = wfx.Format.nSamplesPerSec * wfx.Format.nBlockAlign;
wfx.Format.cbSize = 34;
hr = pAudioClient->IsFormatSupported(AUDCLNT_SHAREMODE_EXCLUSIVE, (WAVEFORMATEX*)&wfx, (WAVEFORMATEX**)pwfx);
if (hr == S_OK)
{
*pwfx = (WAVEFORMATEXTENSIBLE*)CoTaskMemAlloc(sizeof(WAVEFORMATEXTENSIBLE));
memcpy(*pwfx, &wfx, sizeof(WAVEFORMATEXTENSIBLE));
return hr;
} else if (hr == S_FALSE) return hr;
wfx.Format.wFormatTag = WAVE_FORMAT_PCM;
wfx.Format.nChannels = 2;
wfx.Format.wBitsPerSample = 16;
wfx.Format.nSamplesPerSec = 48000;
wfx.Format.nBlockAlign = wfx.Format.nChannels * wfx.Format.wBitsPerSample / 8;
wfx.Format.nAvgBytesPerSec = wfx.Format.nSamplesPerSec * wfx.Format.nBlockAlign;
wfx.Format.cbSize = 22;
hr = pAudioClient->IsFormatSupported(AUDCLNT_SHAREMODE_EXCLUSIVE, (WAVEFORMATEX*)&wfx, (WAVEFORMATEX**)pwfx);
if (hr == S_OK)
{
*pwfx = (WAVEFORMATEXTENSIBLE*)CoTaskMemAlloc(sizeof(WAVEFORMATEXTENSIBLE));
memcpy(*pwfx, &wfx, sizeof(WAVEFORMATEXTENSIBLE));
return hr;
} else if (hr == S_FALSE) return hr;
wfx.Format.wFormatTag = WAVE_FORMAT_PCM;
wfx.Format.nChannels = 2;
wfx.Format.wBitsPerSample = 16;
wfx.Format.nSamplesPerSec = 44100;
wfx.Format.nBlockAlign = wfx.Format.nChannels * wfx.Format.wBitsPerSample / 8;
wfx.Format.nAvgBytesPerSec = wfx.Format.nSamplesPerSec * wfx.Format.nBlockAlign;
wfx.Format.cbSize = 22;
hr = pAudioClient->IsFormatSupported(AUDCLNT_SHAREMODE_EXCLUSIVE, (WAVEFORMATEX*)&wfx, (WAVEFORMATEX**)pwfx);
if (hr == S_OK)
{
*pwfx = (WAVEFORMATEXTENSIBLE*)CoTaskMemAlloc(sizeof(WAVEFORMATEXTENSIBLE));
memcpy(*pwfx, &wfx, sizeof(WAVEFORMATEXTENSIBLE));
return hr;
} else if (hr == S_FALSE) return hr;
wfx.Format.wFormatTag = WAVE_FORMAT_PCM;
wfx.Format.nChannels = 1;
wfx.Format.wBitsPerSample = 16;
wfx.Format.nSamplesPerSec = 48000;
wfx.Format.nBlockAlign = wfx.Format.nChannels * wfx.Format.wBitsPerSample / 8;
wfx.Format.nAvgBytesPerSec = wfx.Format.nSamplesPerSec * wfx.Format.nBlockAlign;
wfx.Format.cbSize = 22;
hr = pAudioClient->IsFormatSupported(AUDCLNT_SHAREMODE_EXCLUSIVE, (WAVEFORMATEX*)&wfx, (WAVEFORMATEX**)pwfx);
if (hr == S_OK)
{
*pwfx = (WAVEFORMATEXTENSIBLE*)CoTaskMemAlloc(sizeof(WAVEFORMATEXTENSIBLE));
memcpy(*pwfx, &wfx, sizeof(WAVEFORMATEXTENSIBLE));
return hr;
} else if (hr == S_FALSE) return hr;
wfx.Format.wFormatTag = WAVE_FORMAT_PCM;
wfx.Format.nChannels = 1;
wfx.Format.wBitsPerSample = 16;
wfx.Format.nSamplesPerSec = 44100;
wfx.Format.nBlockAlign = wfx.Format.nChannels * wfx.Format.wBitsPerSample / 8;
wfx.Format.nAvgBytesPerSec = wfx.Format.nSamplesPerSec * wfx.Format.nBlockAlign;
wfx.Format.cbSize = 22;
hr = pAudioClient->IsFormatSupported(AUDCLNT_SHAREMODE_EXCLUSIVE, (WAVEFORMATEX*)&wfx, (WAVEFORMATEX**)pwfx);
if (hr == S_OK)
{
*pwfx = (WAVEFORMATEXTENSIBLE*)CoTaskMemAlloc(sizeof(WAVEFORMATEXTENSIBLE));
memcpy(*pwfx, &wfx, sizeof(WAVEFORMATEXTENSIBLE));
return hr;
} else if (hr == S_FALSE) return hr;
// Fail
return -1;
}
{
HRESULT hr;
WAVEFORMATEXTENSIBLE wfx;
wfx.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
wfx.Format.nChannels = 6;
wfx.Format.wBitsPerSample = 24;
wfx.Samples.wValidBitsPerSample = 20;
wfx.dwChannelMask = KSAUDIO_SPEAKER_5POINT1;
wfx.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
wfx.Format.nSamplesPerSec = 48000;
wfx.Format.nBlockAlign = wfx.Format.nChannels * wfx.Format.wBitsPerSample / 8;
wfx.Format.nAvgBytesPerSec = wfx.Format.nSamplesPerSec * wfx.Format.nBlockAlign;
wfx.Format.cbSize = 34;
hr = pAudioClient->IsFormatSupported(AUDCLNT_SHAREMODE_EXCLUSIVE, (WAVEFORMATEX*)&wfx, (WAVEFORMATEX**)pwfx);
if (hr == S_OK)
{
*pwfx = (WAVEFORMATEXTENSIBLE*)CoTaskMemAlloc(sizeof(WAVEFORMATEXTENSIBLE));
memcpy(*pwfx, &wfx, sizeof(WAVEFORMATEXTENSIBLE));
return hr;
} else if (hr == S_FALSE) return hr;
wfx.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
wfx.Format.nChannels = 6;
wfx.Format.wBitsPerSample = 24;
wfx.Samples.wValidBitsPerSample = 20;
wfx.dwChannelMask = KSAUDIO_SPEAKER_5POINT1;
wfx.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
wfx.Format.nSamplesPerSec = 44100;
wfx.Format.nBlockAlign = wfx.Format.nChannels * wfx.Format.wBitsPerSample / 8;
wfx.Format.nAvgBytesPerSec = wfx.Format.nSamplesPerSec * wfx.Format.nBlockAlign;
wfx.Format.cbSize = 34;
hr = pAudioClient->IsFormatSupported(AUDCLNT_SHAREMODE_EXCLUSIVE, (WAVEFORMATEX*)&wfx, (WAVEFORMATEX**)pwfx);
if (hr == S_OK)
{
*pwfx = (WAVEFORMATEXTENSIBLE*)CoTaskMemAlloc(sizeof(WAVEFORMATEXTENSIBLE));
memcpy(*pwfx, &wfx, sizeof(WAVEFORMATEXTENSIBLE));
return hr;
} else if (hr == S_FALSE) return hr;
wfx.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
wfx.Format.nChannels = 4;
wfx.Format.wBitsPerSample = 16;
wfx.Samples.wValidBitsPerSample = 16;
wfx.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT;
wfx.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
wfx.Format.nSamplesPerSec = 48000;
wfx.Format.nBlockAlign = wfx.Format.nChannels * wfx.Format.wBitsPerSample / 8;
wfx.Format.nAvgBytesPerSec = wfx.Format.nSamplesPerSec * wfx.Format.nBlockAlign;
wfx.Format.cbSize = 34;
hr = pAudioClient->IsFormatSupported(AUDCLNT_SHAREMODE_EXCLUSIVE, (WAVEFORMATEX*)&wfx, (WAVEFORMATEX**)pwfx);
if (hr == S_OK)
{
*pwfx = (WAVEFORMATEXTENSIBLE*)CoTaskMemAlloc(sizeof(WAVEFORMATEXTENSIBLE));
memcpy(*pwfx, &wfx, sizeof(WAVEFORMATEXTENSIBLE));
return hr;
} else if (hr == S_FALSE) return hr;
wfx.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
wfx.Format.nChannels = 4;
wfx.Format.wBitsPerSample = 16;
wfx.Samples.wValidBitsPerSample = 16;
wfx.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT;
wfx.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
wfx.Format.nSamplesPerSec = 44100;
wfx.Format.nBlockAlign = wfx.Format.nChannels * wfx.Format.wBitsPerSample / 8;
wfx.Format.nAvgBytesPerSec = wfx.Format.nSamplesPerSec * wfx.Format.nBlockAlign;
wfx.Format.cbSize = 34;
hr = pAudioClient->IsFormatSupported(AUDCLNT_SHAREMODE_EXCLUSIVE, (WAVEFORMATEX*)&wfx, (WAVEFORMATEX**)pwfx);
if (hr == S_OK)
{
*pwfx = (WAVEFORMATEXTENSIBLE*)CoTaskMemAlloc(sizeof(WAVEFORMATEXTENSIBLE));
memcpy(*pwfx, &wfx, sizeof(WAVEFORMATEXTENSIBLE));
return hr;
} else if (hr == S_FALSE) return hr;
wfx.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
wfx.Format.nChannels = 2;
wfx.Format.wBitsPerSample = 24;
wfx.Samples.wValidBitsPerSample = 20;
wfx.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT;
wfx.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
wfx.Format.nSamplesPerSec = 48000;
wfx.Format.nBlockAlign = wfx.Format.nChannels * wfx.Format.wBitsPerSample / 8;
wfx.Format.nAvgBytesPerSec = wfx.Format.nSamplesPerSec * wfx.Format.nBlockAlign;
wfx.Format.cbSize = 34;
hr = pAudioClient->IsFormatSupported(AUDCLNT_SHAREMODE_EXCLUSIVE, (WAVEFORMATEX*)&wfx, (WAVEFORMATEX**)pwfx);
if (hr == S_OK)
{
*pwfx = (WAVEFORMATEXTENSIBLE*)CoTaskMemAlloc(sizeof(WAVEFORMATEXTENSIBLE));
memcpy(*pwfx, &wfx, sizeof(WAVEFORMATEXTENSIBLE));
return hr;
} else if (hr == S_FALSE) return hr;
wfx.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
wfx.Format.nChannels = 2;
wfx.Format.wBitsPerSample = 24;
wfx.Samples.wValidBitsPerSample = 20;
wfx.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT;
wfx.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
wfx.Format.nSamplesPerSec = 44100;
wfx.Format.nBlockAlign = wfx.Format.nChannels * wfx.Format.wBitsPerSample / 8;
wfx.Format.nAvgBytesPerSec = wfx.Format.nSamplesPerSec * wfx.Format.nBlockAlign;
wfx.Format.cbSize = 34;
hr = pAudioClient->IsFormatSupported(AUDCLNT_SHAREMODE_EXCLUSIVE, (WAVEFORMATEX*)&wfx, (WAVEFORMATEX**)pwfx);
if (hr == S_OK)
{
*pwfx = (WAVEFORMATEXTENSIBLE*)CoTaskMemAlloc(sizeof(WAVEFORMATEXTENSIBLE));
memcpy(*pwfx, &wfx, sizeof(WAVEFORMATEXTENSIBLE));
return hr;
} else if (hr == S_FALSE) return hr;
wfx.Format.wFormatTag = WAVE_FORMAT_PCM;
wfx.Format.nChannels = 2;
wfx.Format.wBitsPerSample = 16;
wfx.Format.nSamplesPerSec = 48000;
wfx.Format.nBlockAlign = wfx.Format.nChannels * wfx.Format.wBitsPerSample / 8;
wfx.Format.nAvgBytesPerSec = wfx.Format.nSamplesPerSec * wfx.Format.nBlockAlign;
wfx.Format.cbSize = 22;
hr = pAudioClient->IsFormatSupported(AUDCLNT_SHAREMODE_EXCLUSIVE, (WAVEFORMATEX*)&wfx, (WAVEFORMATEX**)pwfx);
if (hr == S_OK)
{
*pwfx = (WAVEFORMATEXTENSIBLE*)CoTaskMemAlloc(sizeof(WAVEFORMATEXTENSIBLE));
memcpy(*pwfx, &wfx, sizeof(WAVEFORMATEXTENSIBLE));
return hr;
} else if (hr == S_FALSE) return hr;
wfx.Format.wFormatTag = WAVE_FORMAT_PCM;
wfx.Format.nChannels = 2;
wfx.Format.wBitsPerSample = 16;
wfx.Format.nSamplesPerSec = 44100;
wfx.Format.nBlockAlign = wfx.Format.nChannels * wfx.Format.wBitsPerSample / 8;
wfx.Format.nAvgBytesPerSec = wfx.Format.nSamplesPerSec * wfx.Format.nBlockAlign;
wfx.Format.cbSize = 22;
hr = pAudioClient->IsFormatSupported(AUDCLNT_SHAREMODE_EXCLUSIVE, (WAVEFORMATEX*)&wfx, (WAVEFORMATEX**)pwfx);
if (hr == S_OK)
{
*pwfx = (WAVEFORMATEXTENSIBLE*)CoTaskMemAlloc(sizeof(WAVEFORMATEXTENSIBLE));
memcpy(*pwfx, &wfx, sizeof(WAVEFORMATEXTENSIBLE));
return hr;
} else if (hr == S_FALSE) return hr;
wfx.Format.wFormatTag = WAVE_FORMAT_PCM;
wfx.Format.nChannels = 1;
wfx.Format.wBitsPerSample = 16;
wfx.Format.nSamplesPerSec = 48000;
wfx.Format.nBlockAlign = wfx.Format.nChannels * wfx.Format.wBitsPerSample / 8;
wfx.Format.nAvgBytesPerSec = wfx.Format.nSamplesPerSec * wfx.Format.nBlockAlign;
wfx.Format.cbSize = 22;
hr = pAudioClient->IsFormatSupported(AUDCLNT_SHAREMODE_EXCLUSIVE, (WAVEFORMATEX*)&wfx, (WAVEFORMATEX**)pwfx);
if (hr == S_OK)
{
*pwfx = (WAVEFORMATEXTENSIBLE*)CoTaskMemAlloc(sizeof(WAVEFORMATEXTENSIBLE));
memcpy(*pwfx, &wfx, sizeof(WAVEFORMATEXTENSIBLE));
return hr;
} else if (hr == S_FALSE) return hr;
wfx.Format.wFormatTag = WAVE_FORMAT_PCM;
wfx.Format.nChannels = 1;
wfx.Format.wBitsPerSample = 16;
wfx.Format.nSamplesPerSec = 44100;
wfx.Format.nBlockAlign = wfx.Format.nChannels * wfx.Format.wBitsPerSample / 8;
wfx.Format.nAvgBytesPerSec = wfx.Format.nSamplesPerSec * wfx.Format.nBlockAlign;
wfx.Format.cbSize = 22;
hr = pAudioClient->IsFormatSupported(AUDCLNT_SHAREMODE_EXCLUSIVE, (WAVEFORMATEX*)&wfx, (WAVEFORMATEX**)pwfx);
if (hr == S_OK)
{
*pwfx = (WAVEFORMATEXTENSIBLE*)CoTaskMemAlloc(sizeof(WAVEFORMATEXTENSIBLE));
memcpy(*pwfx, &wfx, sizeof(WAVEFORMATEXTENSIBLE));
return hr;
} else if (hr == S_FALSE) return hr;
// Fail
return -1;
}
作者: Susan﹏汪汪 发布时间: 2014-04-18
相关阅读 更多
热门阅读
-
office 2019专业增强版最新2021版激活秘钥/序列号/激活码推荐 附激活工具
阅读:74
-
如何安装mysql8.0
阅读:31
-
Word快速设置标题样式步骤详解
阅读:28
-
20+道必知必会的Vue面试题(附答案解析)
阅读:37
-
HTML如何制作表单
阅读:22
-
百词斩可以改天数吗?当然可以,4个步骤轻松修改天数!
阅读:31
-
ET文件格式和XLS格式文件之间如何转化?
阅读:24
-
react和vue的区别及优缺点是什么
阅读:121
-
支付宝人脸识别如何关闭?
阅读:21
-
腾讯微云怎么修改照片或视频备份路径?
阅读:28