Commit bbf947d1 authored by Julien Wadel's avatar Julien Wadel
Browse files

- Add a function to disabling audio enhancements.

- Use options to get human hearing quality.
- Factorize audio format.
- Fix variables that weren't updated in case of different audio format.
- Do not use MixFormat without having set fix parameters (16bits/PCM).
- Fix channel mask.
- Reset Audio Client in case of error.
parent 566a0986
......@@ -20,6 +20,7 @@ along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <initguid.h> // Put it at first or there will be a mess with MMDeviceAPI and PKEY_AudioEndpoint* symbols
#include "mediastreamer2/msfilter.h"
#include "mediastreamer2/mssndcard.h"
......@@ -31,6 +32,12 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include <string>
#include <locale>
#define FREE_PTR(ptr) \
if (ptr != NULL) { \
CoTaskMemFree((LPVOID)ptr); \
ptr = NULL; \
}
const IID IID_IAudioCaptureClient = __uuidof(IAudioCaptureClient);
const IID IID_IAudioRenderClient = __uuidof(IAudioRenderClient);
const IID IID_ISimpleAudioVolume = __uuidof(ISimpleAudioVolume);
......@@ -42,6 +49,100 @@ const CLSID CLSID_MMDeviceEnumerator = __uuidof(MMDeviceEnumerator);
const IID IID_IMMDeviceEnumerator = __uuidof(IMMDeviceEnumerator);
#endif
// Workaround for issues on audio enhancements mode. Check void MSWASAPIReader::init(LPCWSTR id)
#include <MMDeviceAPI.h>
DEFINE_GUID(CLSID_PolicyConfig, 0x870af99c, 0x171d, 0x4f9e, 0xaf, 0x0d, 0xe6, 0x3d, 0xf4, 0x0c, 0x2b, 0xc9);
MIDL_INTERFACE("f8679f50-850a-41cf-9c72-430f290290c8")
IPolicyConfig : public IUnknown
{
public:
virtual HRESULT STDMETHODCALLTYPE GetMixFormat(PCWSTR pszDeviceName, WAVEFORMATEX** ppFormat) = 0;
virtual HRESULT STDMETHODCALLTYPE GetDeviceFormat(PCWSTR pszDeviceName, bool bDefault, WAVEFORMATEX** ppFormat) = 0;
virtual HRESULT STDMETHODCALLTYPE ResetDeviceFormat(PCWSTR pszDeviceName) = 0;
virtual HRESULT STDMETHODCALLTYPE SetDeviceFormat(PCWSTR pszDeviceName, WAVEFORMATEX* ppEndpointFormatFormat, WAVEFORMATEX* pMixFormat) = 0;
virtual HRESULT STDMETHODCALLTYPE GetProcessingPeriod(PCWSTR pszDeviceName, bool bDefault, PINT64 pmftDefaultPeriod, PINT64 pmftMinimumPeriod) = 0;
virtual HRESULT STDMETHODCALLTYPE SetProcessingPeriod(PCWSTR pszDeviceName, PINT64 pmftPeriod) = 0;
virtual HRESULT STDMETHODCALLTYPE GetShareMode(PCWSTR pszDeviceName, struct DeviceShareMode* pMode) = 0;
virtual HRESULT STDMETHODCALLTYPE SetShareMode(PCWSTR pszDeviceName, struct DeviceShareMode* pMode) = 0;
virtual HRESULT STDMETHODCALLTYPE GetPropertyValue(PCWSTR pszDeviceName, BOOL bFxStore, const PROPERTYKEY& pKey, PROPVARIANT* pv) = 0;
virtual HRESULT STDMETHODCALLTYPE SetPropertyValue(PCWSTR pszDeviceName, BOOL bFxStore, const PROPERTYKEY& pKey, PROPVARIANT* pv) = 0;
virtual HRESULT STDMETHODCALLTYPE SetDefaultEndpoint(PCWSTR pszDeviceName, int eRole) = 0;
virtual HRESULT STDMETHODCALLTYPE SetEndpointVisibility(PCWSTR pszDeviceName, bool bVisible) = 0;
};
MSWasapi::MSWasapi(const std::string& mediaDirectionStr) : mAudioClient(NULL){
mMediaDirectionStr = mediaDirectionStr;
mRate = 8000;
mNChannels = 1;
mWBitsPerSample = 16; // The SDK limit to 16 bits
mNBlockAlign = mWBitsPerSample * mNChannels / 8;
mDisableSysFx = false;
}
void MSWasapi::changePolicies(IMMDevice *device){
HRESULT result;
if( mDisableSysFx) { // Workaround: Remove enhancements mode as it can lead to break inputs on some systems
LPWSTR endpointId = NULL;
result = device->GetId(&endpointId);
IPolicyConfig* policyConfig;
result = CoCreateInstance(CLSID_PolicyConfig, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&policyConfig));
REPORT_ERROR(("mswasapi: Disabling audio enhancements requested but could not get policy config for audio " + mMediaDirectionStr).c_str(), result);
PROPVARIANT var;
PropVariantInit(&var);
result = policyConfig->GetPropertyValue(endpointId, TRUE, PKEY_AudioEndpoint_Disable_SysFx, &var);
var.uiVal = (USHORT)1;
result = policyConfig->SetPropertyValue(endpointId, TRUE, PKEY_AudioEndpoint_Disable_SysFx, &var);
policyConfig->Release();
}
error:
return;
}
void MSWasapi::updateFormat(bool useBestFormat){
if(useBestFormat ) {
useBestFormat = false;
WAVEFORMATEX *pWfx = NULL;
HRESULT result = mAudioClient->GetMixFormat(&pWfx); // Get best format for shared mode.
REPORT_ERROR(("Could not get the mix format of the MSWASAPI audio "+mMediaDirectionStr+" interface [%x]").c_str(), result);
mRate = pWfx->nSamplesPerSec;
mNChannels = pWfx->nChannels;
FREE_PTR(pWfx);
useBestFormat = true;
}
error:
mWBitsPerSample = 16; // The SDK limit to 16 bits
if(!useBestFormat){
// Initialize the frame rate and the number of channels to be able to generate silence.
mRate = 8000;
mNChannels = 1;
}
mNBlockAlign = mWBitsPerSample * mNChannels / 8;
}
WAVEFORMATPCMEX MSWasapi::buildFormat() const{
WAVEFORMATPCMEX wfx;
wfx.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
wfx.Format.nChannels = (WORD)mNChannels;
wfx.Format.nSamplesPerSec = mRate;
wfx.Format.wBitsPerSample = (WORD)mWBitsPerSample;
wfx.Format.nAvgBytesPerSec = (DWORD)mRate * mNChannels * mWBitsPerSample / 8;
wfx.Format.nBlockAlign = (WORD)mNBlockAlign;
wfx.Format.cbSize = sizeof (WAVEFORMATEXTENSIBLE) - sizeof (WAVEFORMATEX);
wfx.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
wfx.Samples.wValidBitsPerSample = mWBitsPerSample;
switch(mNChannels){
case 1: wfx.dwChannelMask = SPEAKER_FRONT_CENTER; break;
case 2: wfx.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT; break;
case 4: wfx.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT; break;
case 6: wfx.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT; break;
case 8: wfx.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT | SPEAKER_FRONT_LEFT_OF_CENTER | SPEAKER_FRONT_RIGHT_OF_CENTER; break;
default: wfx.dwChannelMask = 0; break;
}
return wfx;
}
/******************************************************************************
* Methods to (de)initialize and run the WASAPI sound capture filter *
*****************************************************************************/
......
......@@ -69,6 +69,26 @@ typedef struct WasapiSndCard {
LPWSTR id;
} WasapiSndCard;
class MSWasapi{
public:
#if defined(MS2_WINDOWS_PHONE) || defined(MS2_WINDOWS_UNIVERSAL)
IAudioClient2 *mAudioClient;
#else
IAudioClient *mAudioClient;
#endif
int mRate;
int mNChannels;
int mNBlockAlign;
int mWBitsPerSample;
std::string mMediaDirectionStr;
bool mDisableSysFx; // Option to remove audio enhancements mode. This mode can break inputs on some systems.
MSWasapi(const std::string& mediaDirectionStr);
void changePolicies(IMMDevice *device);
void updateFormat(bool useBestFormat);
WAVEFORMATPCMEX buildFormat() const;
};
extern const IID IID_IAudioClient2;
extern const IID IID_IAudioCaptureClient;
......
......@@ -20,12 +20,10 @@ along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "mediastreamer2/mscommon.h"
#include "mediastreamer2/msticker.h"
#include "mswasapi_reader.h"
#define REFTIME_250MS 2500000
#define RELEASE_CLIENT(client) \
......@@ -43,8 +41,10 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
bool MSWASAPIReader::smInstantiated = false;
MSWASAPIReader::MSWASAPIReader(MSFilter *filter)
: mAudioClient(NULL), mAudioCaptureClient(NULL), mVolumeControler(NULL), mBufferFrameCount(0), mIsInitialized(false), mIsActivated(false), mIsStarted(false), mFilter(filter)
: MSWasapi("input"), mAudioCaptureClient(NULL), mVolumeControler(NULL), mBufferFrameCount(0), mIsInitialized(false), mIsActivated(false), mIsStarted(false), mFilter(filter)
{
mTickerSynchronizer = ms_ticker_synchronizer_new();
#ifdef MS2_WINDOWS_UNIVERSAL
......@@ -75,6 +75,7 @@ MSWASAPIReader::~MSWASAPIReader()
void MSWASAPIReader::init(LPCWSTR id)
{
bool useBestFormat = false;
HRESULT result;
WAVEFORMATEX *pWfx = NULL;
#if defined(MS2_WINDOWS_PHONE) || defined(MS2_WINDOWS_UNIVERSAL)
......@@ -127,6 +128,7 @@ void MSWASAPIReader::init(LPCWSTR id)
result = pEnumerator->GetDevice(mCaptureId, &pDevice);
SAFE_RELEASE(pEnumerator);
REPORT_ERROR("mswasapi: Could not get the capture device", result);
changePolicies(pDevice);
result = pDevice->Activate(IID_IAudioClient, CLSCTX_ALL, NULL, (void **)&mAudioClient);
SAFE_RELEASE(pDevice);
REPORT_ERROR("mswasapi: Could not activate the capture device", result);
......@@ -138,23 +140,14 @@ void MSWASAPIReader::init(LPCWSTR id)
result = mAudioClient->SetClientProperties(&properties);
REPORT_ERROR("Could not set properties of the MSWASAPI audio input interface [%x]", result);
#endif
result = mAudioClient->GetMixFormat(&pWfx);
REPORT_ERROR("Could not get the mix format of the MSWASAPI audio input interface [%x]", result);
mRate = pWfx->nSamplesPerSec;
mNChannels = pWfx->nChannels;
mNBlockAlign = pWfx->nBlockAlign;
FREE_PTR(pWfx);
useBestFormat = true;
error:
updateFormat(useBestFormat);
mIsInitialized = true;
smInstantiated = true;
activate();
return;
error:
// Initialize the frame rate and the number of channels to be able to generate silence.
mRate = 8000;
mNChannels = 1;
mNBlockAlign = 16 * 1 / 8;
return;
}
int MSWASAPIReader::activate()
......@@ -170,22 +163,12 @@ int MSWASAPIReader::activate()
#if defined( MS2_WINDOWS_PHONE )
flags = AUDCLNT_SESSIONFLAGS_EXPIREWHENUNOWNED | AUDCLNT_SESSIONFLAGS_DISPLAY_HIDE | AUDCLNT_SESSIONFLAGS_DISPLAY_HIDEWHENEXPIRED;
#else
flags = AUDCLNT_STREAMFLAGS_NOPERSIST | AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM | AUDCLNT_STREAMFLAGS_SRC_DEFAULT_QUALITY;
#endif
proposedWfx.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
proposedWfx.Format.nChannels = (WORD)mNChannels;
proposedWfx.Format.nSamplesPerSec = mRate;
proposedWfx.Format.wBitsPerSample = 16;
proposedWfx.Format.nAvgBytesPerSec = mRate * mNChannels * proposedWfx.Format.wBitsPerSample / 8;
proposedWfx.Format.nBlockAlign = (WORD)(proposedWfx.Format.wBitsPerSample * mNChannels / 8);
proposedWfx.Format.cbSize = 22;
proposedWfx.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
proposedWfx.Samples.wValidBitsPerSample = proposedWfx.Format.wBitsPerSample;
if (mNChannels == 1) {
proposedWfx.dwChannelMask = SPEAKER_FRONT_CENTER;
} else {
proposedWfx.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT;
}
proposedWfx = buildFormat();
result = mAudioClient->IsFormatSupported(AUDCLNT_SHAREMODE_SHARED, (WAVEFORMATEX *)&proposedWfx, &pSupportedWfx);
if (result == S_OK) {
pUsedWfx = (WAVEFORMATEX *)&proposedWfx;
......@@ -197,16 +180,11 @@ int MSWASAPIReader::activate()
result = mAudioClient->Initialize(AUDCLNT_SHAREMODE_SHARED, flags, requestedDuration, 0, pUsedWfx, NULL);
if ((result != S_OK) && (result != AUDCLNT_E_ALREADY_INITIALIZED)) {
mAudioClient->Reset();
result = mAudioClient->GetMixFormat(&pSupportedWfx);
pUsedWfx = pSupportedWfx;
result = mAudioClient->Initialize(AUDCLNT_SHAREMODE_SHARED, flags, requestedDuration, 0, pUsedWfx, NULL);
if ((result != S_OK) && (result != AUDCLNT_E_ALREADY_INITIALIZED)) {
mAudioClient->Reset();
REPORT_ERROR("Could not initialize the MSWASAPI audio input interface [%x]", result);
}
REPORT_ERROR("Could not initialize the MSWASAPI audio input interface [%x]", result);
}
mNBlockAlign = pUsedWfx->nBlockAlign;
mRate = pUsedWfx->nSamplesPerSec;
mNChannels = pUsedWfx->nChannels;
result = mAudioClient->GetBufferSize(&mBufferFrameCount);
REPORT_ERROR("Could not get buffer size for the MSWASAPI audio input interface [%x]", result);
ms_message("MSWASAPI audio input interface buffer size: %i", mBufferFrameCount);
......@@ -216,12 +194,13 @@ int MSWASAPIReader::activate()
REPORT_ERROR("Could not get volume control service from the MSWASAPI audio input interface [%x]", result);
mIsActivated = true;
ms_message("Wasapi capture initialized at %i Hz, %i channels, with buffer size %i (%i ms), %i-bit frames are on %i bits", (int)mRate, (int)mNChannels,
(int)mBufferFrameCount, (int)1000*mBufferFrameCount/(mNChannels*2* mRate), (int)pUsedWfx->wBitsPerSample, mNBlockAlign*8);
(int)mBufferFrameCount, (int)1000*mBufferFrameCount/ mRate, (int)pUsedWfx->wBitsPerSample, mNBlockAlign*8);
FREE_PTR(pSupportedWfx);
return 0;
error:
FREE_PTR(pSupportedWfx);
if(mAudioClient) mAudioClient->Reset();
return -1;
}
......
......@@ -32,7 +32,9 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
class MSWASAPIReader
#ifdef MS2_WINDOWS_UNIVERSAL
: public RuntimeClass< RuntimeClassFlags< ClassicCom >, FtmBase, IActivateAudioInterfaceCompletionHandler >
: public MSWasapi, RuntimeClass< RuntimeClassFlags< ClassicCom >, FtmBase, IActivateAudioInterfaceCompletionHandler >
#else
: public MSWasapi
#endif
{
public:
......@@ -67,11 +69,6 @@ private:
HANDLE mActivationEvent;
#else
LPCWSTR mCaptureId;
#endif
#if defined(MS2_WINDOWS_PHONE) || defined(MS2_WINDOWS_UNIVERSAL)
IAudioClient2 *mAudioClient;
#else
IAudioClient *mAudioClient;
#endif
IAudioCaptureClient *mAudioCaptureClient;
ISimpleAudioVolume *mVolumeControler;
......@@ -79,9 +76,7 @@ private:
bool mIsInitialized;
bool mIsActivated;
bool mIsStarted;
int mRate;
int mNChannels;
int mNBlockAlign;
MSFilter *mFilter;
MSTickerSynchronizer *mTickerSynchronizer;
};
......
......@@ -47,7 +47,7 @@ bool MSWASAPIWriter::smInstantiated = false;
MSWASAPIWriter::MSWASAPIWriter()
: mAudioClient(NULL), mAudioRenderClient(NULL), mVolumeControler(NULL), mBufferFrameCount(0), mIsInitialized(false), mIsActivated(false), mIsStarted(false)
: MSWasapi("output"), mAudioRenderClient(NULL), mVolumeControler(NULL), mBufferFrameCount(0), mIsInitialized(false), mIsActivated(false), mIsStarted(false)
{
#ifdef MS2_WINDOWS_UNIVERSAL
mActivationEvent = CreateEventEx(NULL, NULL, 0, EVENT_ALL_ACCESS);
......@@ -75,6 +75,7 @@ MSWASAPIWriter::~MSWASAPIWriter()
void MSWASAPIWriter::init(LPCWSTR id, MSFilter *f) {
bool useBestFormat = false;
HRESULT result;
WAVEFORMATEX *pWfx = NULL;
#if defined(MS2_WINDOWS_PHONE) || defined(MS2_WINDOWS_UNIVERSAL)
......@@ -127,6 +128,7 @@ void MSWASAPIWriter::init(LPCWSTR id, MSFilter *f) {
result = pEnumerator->GetDevice(mRenderId, &pDevice);
SAFE_RELEASE(pEnumerator);
REPORT_ERROR("mswasapi: Could not get the rendering device", result);
changePolicies(pDevice);
result = pDevice->Activate(IID_IAudioClient, CLSCTX_ALL, NULL, (void **)&mAudioClient);
SAFE_RELEASE(pDevice);
REPORT_ERROR("mswasapi: Could not activate the rendering device", result);
......@@ -138,23 +140,15 @@ void MSWASAPIWriter::init(LPCWSTR id, MSFilter *f) {
result = mAudioClient->SetClientProperties(&properties);
REPORT_ERROR("Could not set properties of the MSWASAPI audio output interface [%x]", result);
#endif
result = mAudioClient->GetMixFormat(&pWfx);
REPORT_ERROR("Could not get the mix format of the MSWASAPI audio output interface [%x]", result);
mRate = pWfx->nSamplesPerSec;
mNChannels = pWfx->nChannels;
mNBlockAlign = pWfx->nBlockAlign; // Get the selected bock size
FREE_PTR(pWfx);
useBestFormat = true;
error:
updateFormat(useBestFormat);
mIsInitialized = true;
smInstantiated = true;
activate();
return;
error:
// Initialize the frame rate and the number of channels to prevent configure a resampler with crappy parameters.
mRate = 8000;
mNChannels = 1;
mNBlockAlign = 16 * 1 / 8;
return;
}
int MSWASAPIWriter::activate()
......@@ -171,27 +165,15 @@ int MSWASAPIWriter::activate()
result = mAudioClient->GetDevicePeriod(&devicePeriod, NULL);
if (result != S_OK) {
ms_error("MSWASAPIWriter: GetDevicePeriod() failed.");
ms_warning("MSWASAPIWriter: GetDevicePeriod() failed.");
}
devicePeriodMs = (int)(devicePeriod / 10000);
/*Compute our requested buffer duration.*/
requestedBufferDuration = minBufferDurationMs * 1000LL * 100LL;
requestedBufferDuration = minBufferDurationMs * 10000LL; // requestedBufferDuration is expressed in 100-nanoseconds units
proposedWfx = buildFormat();
proposedWfx.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
proposedWfx.Format.nChannels = (WORD)mNChannels;
proposedWfx.Format.nSamplesPerSec = mRate;
proposedWfx.Format.wBitsPerSample = 16;
proposedWfx.Format.nAvgBytesPerSec = mRate * mNChannels * proposedWfx.Format.wBitsPerSample / 8;
proposedWfx.Format.nBlockAlign = (WORD)(proposedWfx.Format.wBitsPerSample * mNChannels / 8);
proposedWfx.Format.cbSize = 22;
proposedWfx.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
proposedWfx.Samples.wValidBitsPerSample = proposedWfx.Format.wBitsPerSample;
if (mNChannels == 1) {
proposedWfx.dwChannelMask = SPEAKER_FRONT_CENTER;
} else {
proposedWfx.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT;
}
result = mAudioClient->IsFormatSupported(AUDCLNT_SHAREMODE_SHARED, (WAVEFORMATEX *)&proposedWfx, &pSupportedWfx);
if (result == S_OK) {
pUsedWfx = (WAVEFORMATEX *)&proposedWfx;
......@@ -200,11 +182,14 @@ int MSWASAPIWriter::activate()
} else {
REPORT_ERROR("Audio format not supported by the MSWASAPI audio output interface [%x]", result);
}
result = mAudioClient->Initialize(AUDCLNT_SHAREMODE_SHARED, AUDCLNT_STREAMFLAGS_NOPERSIST, requestedBufferDuration, 0, pUsedWfx, NULL);
// Use best quality intended to be heard by humans.
result = mAudioClient->Initialize(AUDCLNT_SHAREMODE_SHARED, AUDCLNT_STREAMFLAGS_NOPERSIST | AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM | AUDCLNT_STREAMFLAGS_SRC_DEFAULT_QUALITY , requestedBufferDuration, 0, pUsedWfx, NULL);
if ((result != S_OK) && (result != AUDCLNT_E_ALREADY_INITIALIZED)) {
REPORT_ERROR("Could not initialize the MSWASAPI audio output interface [%x]", result);
}
mNBlockAlign = pUsedWfx->nBlockAlign;
mRate = pUsedWfx->nSamplesPerSec;
mNChannels = pUsedWfx->nChannels;
result = mAudioClient->GetBufferSize(&mBufferFrameCount);
REPORT_ERROR("Could not get buffer size for the MSWASAPI audio output interface [%x]", result);
result = mAudioClient->GetService(IID_IAudioRenderClient, (void **)&mAudioRenderClient);
......@@ -214,12 +199,13 @@ int MSWASAPIWriter::activate()
mIsActivated = true;
ms_message("Wasapi playback output initialized at %i Hz, %i channels, with buffer size %i (%i ms), device period is %i, %i-bit frames are on %i bits", (int)mRate, (int)mNChannels,
(int)mBufferFrameCount, (int)1000*mBufferFrameCount/(mNChannels*2* mRate), devicePeriodMs, (int)pUsedWfx->wBitsPerSample, mNBlockAlign*8);
(int)mBufferFrameCount, (int)1000*mBufferFrameCount/ mRate, devicePeriodMs, (int)pUsedWfx->wBitsPerSample, mNBlockAlign*8);
FREE_PTR(pSupportedWfx);
return 0;
error:
FREE_PTR(pSupportedWfx);
if(mAudioClient) mAudioClient->Reset();
return -1;
}
......@@ -279,7 +265,8 @@ int MSWASAPIWriter::feed(MSFilter *f){
msgpullup(im, -1);
if (inputFrames > (int)numFramesWritable) {
/*This case should not happen because of upstream flow control, except in rare disaster cases.*/
ms_error("MSWASAPIWriter: cannot write output buffer of %i samples, not enough space.", inputFrames);
if(mMinFrameCount != -1)
ms_error("MSWASAPIWriter: cannot write output buffer of %i samples, not enough space [%i=%i-%i].", inputFrames, numFramesWritable,mBufferFrameCount,numFramesPadding);
}else {
BYTE *buffer;
result = mAudioRenderClient->GetBuffer(inputFrames, &buffer);
......
......@@ -32,7 +32,9 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
class MSWASAPIWriter
#ifdef MS2_WINDOWS_UNIVERSAL
: public RuntimeClass< RuntimeClassFlags< ClassicCom >, FtmBase, IActivateAudioInterfaceCompletionHandler >
: public MSWasapi, RuntimeClass< RuntimeClassFlags< ClassicCom >, FtmBase, IActivateAudioInterfaceCompletionHandler >
#else
: public MSWasapi
#endif
{
public:
......@@ -69,11 +71,6 @@ private:
HANDLE mActivationEvent;
#else
LPCWSTR mRenderId;
#endif
#if defined(MS2_WINDOWS_PHONE) || defined(MS2_WINDOWS_UNIVERSAL)
IAudioClient2 *mAudioClient;
#else
IAudioClient *mAudioClient;
#endif
IAudioRenderClient *mAudioRenderClient;
ISimpleAudioVolume *mVolumeControler;
......@@ -82,9 +79,6 @@ private:
bool mIsInitialized;
bool mIsActivated;
bool mIsStarted;
int mRate;
int mNChannels;
int mNBlockAlign;
};
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment